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
| Format | Example | Best For |
|---|---|---|
| Named | tomato | Prototyping only |
| Hex | #6c63ff | Standard — most used |
| RGB | rgb(108, 99, 255) | When you need opacity variation |
| HSL | hsl(245, 80%, 70%) | Design iteration, palette building |
| OKLCH | oklch(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?
- Wide gamut (P3) color support for modern displays.
- Perceptually uniform —
L: 65%feels equally bright regardless of hue. - Better for accessibility — it's easier to ensure correct contrast ratios.
- 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 Size | Minimum (AA) | Enhanced (AAA) |
|---|---|---|
| Normal text (< 18pt) | 4.5:1 | 7:1 |
| Large text (≥ 18pt or 14pt bold) | 3:1 | 4.5:1 |
| UI components / graphics | 3: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.