Skip to main content

CSS Color Systems and Design Token Palettes

Color is the most emotionally impactful design decision you make. CSS provides multiple color systems — from simple keywords to modern perceptual color spaces. This page covers them all and shows how to build a production-ready color system for AI-assisted design.

1. Color Formats: Quick Comparison

FormatExampleBest For
NamedtomatoPrototyping only
Hex#6c63ffStandard — most used
RGBrgb(108, 99, 255)When you need opacity variation
HSLhsl(245, 80%, 70%)Design iteration, palette building
OKLCHoklch(60% 0.2 265)Modern, accessible, P3-wide gamut

2. Named Colors

CSS has 140 named colors — the exhaustive list includes every web-safe and CSS-defined color by keyword. Good for quick prototypes, bad for production (hardcoded, not maintainable).

.danger { color: tomato; }
.success { color: mediumseagreen; }
.muted { color: slategray; }
.bg { background: aliceblue; }

3. Hexadecimal

The most widely used format. #RRGGBB — each pair 00–FF = 0–255 intensity for R, G, B.

/* Full 6-digit */
.primary { color: #6c63ff; }

/* 3-digit shorthand — #RGB expands to #RRGGBB */
.black { color: #000; } /* = #000000 */
.white { color: #fff; } /* = #ffffff */

/* 8-digit with alpha: #RRGGBBAA */
.overlay { background: #0f0f0f99; } /* ~60% opacity black */

4. RGB and RGBA

.primary { color: rgb(108, 99, 255); }
.transparent { background: rgba(108, 99, 255, 0.15); } /* 15% opacity */

/* Modern syntax (CSS Level 4) — same result */
.modern { color: rgb(108 99 255 / 15%); }

Power technique: Store RGB values in a variable for flexible opacity usage:

:root { --color-primary-rgb: 108, 99, 255; }

.card-hover { background: rgba(var(--color-primary-rgb), 0.1); }
.glow { box-shadow: 0 0 20px rgba(var(--color-primary-rgb), 0.4); }

5. HSL — The Designer's Color System

HSL (Hue, Saturation, Lightness) maps to how designers think about color:

  • Hue 0–360°: Position on the color wheel (0=red, 120=green, 240=blue).
  • Saturation 0–100%: Vividness (0% = gray, 100% = full color).
  • Lightness 0–100%: Darkness to lightness (0% = black, 50% = color, 100% = white).
/* Generate full palette from one hue */
:root {
--hue: 245; /* Purple-blue */

--color-primary: hsl(var(--hue), 80%, 62%);
--color-primary-dark: hsl(var(--hue), 80%, 48%); /* Just change L */
--color-primary-light:hsl(var(--hue), 80%, 80%);
--color-primary-muted:hsl(var(--hue), 30%, 65%); /* Lower S */
--color-primary-bg: hsl(var(--hue), 60%, 95%); /* Very light */
--color-primary-glow: hsla(var(--hue), 80%, 62%, 0.3);
}

Complementary color = hue + 180°:

:root {
--hue-primary: 245;
--hue-complementary: calc(var(--hue-primary) + 180); /* = 65 — yellow-green */
}

6. OKLCH — The Modern Standard

oklch() (Oklab Lightness Chroma Hue) is the most perceptually accurate system available in CSS. It was designed to fix the limitations of HSL where:

  • Equal lightness values feel unequal (blue at L=50% looks darker than yellow at L=50%).
  • Hue shifts unexpectedly when increasing saturation.
/* oklch(Lightness% Chroma Hue) */
.primary { color: oklch(65% 0.22 265); } /* Vivid purple */
.lighter { color: oklch(82% 0.12 265); } /* Same hue, lighter — truly lighter */
.darker { color: oklch(42% 0.22 265); } /* Same hue, darker */
.muted { color: oklch(65% 0.08 265); } /* Same hue, less saturated */

/* With opacity */
.overlay { background: oklch(65% 0.22 265 / 20%); }

Why Use OKLCH in Your Token System?

  1. Wide gamut (P3) color support for modern displays.
  2. Perceptually uniform — L: 65% feels equally bright regardless of hue.
  3. Better for accessibility — it's easier to ensure correct contrast ratios.
  4. AI tools increasingly output OKLCH values.

7. Building a Complete Color Token System

:root {
/* ── Palette (raw) ── */
--palette-purple-50: oklch(97% 0.03 265);
--palette-purple-100: oklch(92% 0.06 265);
--palette-purple-500: oklch(62% 0.22 265); /* ← primary brand */
--palette-purple-700: oklch(45% 0.22 265);
--palette-purple-900: oklch(25% 0.15 265);

/* ── Semantic tokens ── */
--color-primary: var(--palette-purple-500);
--color-primary-hover: var(--palette-purple-700);
--color-bg: #0f0f0f;
--color-surface: #1a1a1a;
--color-text: #f0f0f0;
--color-text-muted: #888888;
--color-border: rgba(255, 255, 255, 0.08);
--color-danger: oklch(55% 0.22 25); /* Red */
--color-success: oklch(60% 0.2 145); /* Green */
--color-warning: oklch(72% 0.18 80); /* Yellow */
--color-info: oklch(62% 0.18 245); /* Blue */
}

8. Color Accessibility: Contrast Ratios

WCAG 2.1 requires minimum contrast between text and background:

Text SizeMinimum (AA)Enhanced (AAA)
Normal text (< 18pt)4.5:17:1
Large text (≥ 18pt or 14pt bold)3:14.5:1
UI components / graphics3:1

Quick check: Chrome DevTools → click any color swatch in Styles panel → contrast ratio shown with ✅/❌.

AI workflow: Ask Claude/ChatGPT: "Check if #f0f0f0 on #1a1a1a passes WCAG AA." or use WebAIM Contrast Checker.