coloris.js

Save Color

coloris.js generates primative CSS variables from your accent and background colors based on Radix Colors .

:root {
  /* Accent Scale */
  --accent-1: oklch(99.4% 0.0011 106.4);
  --accent-2: oklch(98.2% 0.0015 106.4);
  --accent-3: oklch(95.6% 0.0023 97.61);
  --accent-4: oklch(93.2% 0.0034 100.6);
  --accent-5: oklch(91% 0.0038 95.91);
  --accent-6: oklch(88.6% 0.005 98.34);
  --accent-7: oklch(85.3% 0.0062 96.6);
  --accent-8: oklch(79.2% 0.0083 96.5);
  --accent-9: oklch(0% 0 none);
  --accent-10: oklch(30% 0.0079 96.31);
  --accent-11: oklch(49.8% 0.0079 106.7);
  --accent-12: oklch(24.3% 0.0079 96.31);

  /* Neutral Scale */
  --neutral-1: oklch(99.4% 0.0011 106.4);
  --neutral-2: oklch(98.2% 0.0015 106.4);
  --neutral-3: oklch(95.6% 0.0023 97.61);
  --neutral-4: oklch(93.2% 0.0034 100.6);
  --neutral-5: oklch(91% 0.0038 95.91);
  --neutral-6: oklch(88.6% 0.005 98.34);
  --neutral-7: oklch(85.3% 0.0062 96.6);
  --neutral-8: oklch(79.2% 0.0083 96.5);
  --neutral-9: oklch(64.1% 0.0103 106.7);
  --neutral-10: oklch(60.6% 0.0096 106.7);
  --neutral-11: oklch(49.8% 0.0079 106.7);
  --neutral-12: oklch(24.3% 0.0079 96.31);

  /* Accent Scale Alpha */
  --accent-a1: color(display-p3 0.349 0.349 0.0235 / 0.012);
  --accent-a2: color(display-p3 0.1608 0.1608 0.0235 / 0.028);
  --accent-a3: color(display-p3 0.1294 0.0667 0.0078 / 0.063);
  --accent-a4: color(display-p3 0.1294 0.1294 0.0118 / 0.099);
  --accent-a5: color(display-p3 0.1255 0.098 0.0078 / 0.13);
  --accent-a6: color(display-p3 0.102 0.0745 0.0039 / 0.161);
  --accent-a7: color(display-p3 0.098 0.098 0.0039 / 0.208);
  --accent-a8: color(display-p3 0.0863 0.0745 0.0039 / 0.287);
  --accent-a9: color(display-p3 0 0 0);
  --accent-a10: color(display-p3 0.0275 0.0235 0 / 0.84);
  --accent-a11: color(display-p3 0.0314 0.0314 0 / 0.632);
  --accent-a12: color(display-p3 0.0235 0.0196 0 / 0.891);

  /* Neutral Scale Alpha */
  --neutral-a1: color(display-p3 0.349 0.349 0.0235 / 0.012);
  --neutral-a2: color(display-p3 0.1608 0.1608 0.0235 / 0.028);
  --neutral-a3: color(display-p3 0.1294 0.0667 0.0078 / 0.063);
  --neutral-a4: color(display-p3 0.1294 0.1294 0.0118 / 0.099);
  --neutral-a5: color(display-p3 0.1255 0.098 0.0078 / 0.13);
  --neutral-a6: color(display-p3 0.102 0.0745 0.0039 / 0.161);
  --neutral-a7: color(display-p3 0.098 0.098 0.0039 / 0.208);
  --neutral-a8: color(display-p3 0.0863 0.0745 0.0039 / 0.287);
  --neutral-a9: color(display-p3 0.051 0.051 0.0039 / 0.471);
  --neutral-a10: color(display-p3 0.0392 0.0392 0 / 0.51);
  --neutral-a11: color(display-p3 0.0314 0.0314 0 / 0.632);
  --neutral-a12: color(display-p3 0.0235 0.0196 0 / 0.891);

  /* Surfaces */
  --neutral-surface: color(display-p3 1 1 1 / 80%);
  --accent-surface: color(display-p3 0.9725 0.9725 0.9647 / 0.8);

  /* Fallback for browsers that don't support P3 */
  @supports not (color: color(display-p3 1 1 1)) {
    /* Accent Scale */
    --accent-1: #fdfdfc;
    --accent-2: #f9f9f8;
    --accent-3: #f1f0ef;
    --accent-4: #e9e9e6;
    --accent-5: #e2e1de;
    --accent-6: #dad9d6;
    --accent-7: #cfcfca;
    --accent-8: #bcbbb5;
    --accent-9: #000;
    --accent-10: #2f2e29;
    --accent-11: #63635e;
    --accent-12: #21201c;

    /* Neutral Scale */
    --neutral-1: #fdfdfc;
    --neutral-2: #f9f9f8;
    --neutral-3: #f1f0ef;
    --neutral-4: #e9e9e6;
    --neutral-5: #e2e1de;
    --neutral-6: #dad9d6;
    --neutral-7: #cfcfca;
    --neutral-8: #bcbbb5;
    --neutral-9: #8d8d86;
    --neutral-10: #82827c;
    --neutral-11: #63635e;
    --neutral-12: #21201c;

    /* Accent Scale Alpha */
    --accent-a1: #55550003;
    --accent-a2: #25250007;
    --accent-a3: #20100010;
    --accent-a4: #1f1f0019;
    --accent-a5: #1f180021;
    --accent-a6: #19130029;
    --accent-a7: #19190035;
    --accent-a8: #1915014a;
    --accent-a9: #000000;
    --accent-a10: #070600d6;
    --accent-a11: #080800a1;
    --accent-a12: #060500e3;

    /* Neutral Scale Alpha */
    --neutral-a1: #55550003;
    --neutral-a2: #25250007;
    --neutral-a3: #20100010;
    --neutral-a4: #1f1f0019;
    --neutral-a5: #1f180021;
    --neutral-a6: #19130029;
    --neutral-a7: #19190035;
    --neutral-a8: #1915014a;
    --neutral-a9: #0f0f0079;
    --neutral-a10: #0c0c0083;
    --neutral-a11: #080800a1;
    --neutral-a12: #060500e3;

    /* Surfaces */
    --neutral-surface: #ffffffcc;
    --accent-surface: #f8f8f6cc;
  }

  /* Common properties */
  --background: #fff;
  --accent-contrast: #fff;
}

Using these variables, you can create your own sematic color system. For example, for shadcn/ui:

@layer theme {
  :root {
    --bg: var(--background);
    --fg: var(--neutral-12);

    --muted: var(--neutral-surface);
    --muted-foreground: var(--neutral-11);

    --popover: var(--background);
    --popover-foreground: var(--neutral-12);
  
    --border: var(--neutral-7);
    --input: var(--neutral-7);

    --primary: var(--accent-9);
    --primary-foreground: var(--accent-contrast);

    --secondary: var(--neutral-3);
    --secondary-foreground: var(--neutral-12);

    --outline: var(--neutral-12);
    --ring: var(--neutral-12);
  }
}

Use it as an one-off or programmatic color palette generator.

One-off projects

Use this web app to generate primative CSS variables for your accent and background colors. Copy the code and remove the variables you don't need.

Multi-theme platform with global design system

Install the coloris-js package.

npm install coloris-js

Generate CSS variables.

import { coloris } from "coloris-js";

const colors = coloris({
  appearance: "light",
  accent: "#BCFB46",
  background: "#ffffff",
  neutral: "sand",
});

Use in React server components.

import { coloris } from "coloris-js";
import { getTheme } from "@/lib/fetchers";

export default async function Layout({
  children,
  params,
}: {
  children: React.ReactNode;
  params: { id: string };
}) {
  const { id } = params;
  const theme = await getTheme(id);
  const { accent, background, neutral } = theme;

  const colors = coloris({
    appearance: "light",
    accent,
    background,
    neutral,
  });

  return (
    <>
      <style>{colors}</style>
      {children}
    </>
  );
}