PageWeave/Design

Guides / Design / Color in OKLCH

3 Design coloroklchcontrastpalette .md

Color in OKLCH

Why OKLCH changes how you choose colors, and how to build palettes that survive dark mode.

OKLCH describes color the way humans perceive it: L (lightness), C (chroma/saturation), H (hue). It's the native format of daisyUI 5 themes and the reason modern palettes stop fighting you.

Why it matters

In hex/HSL, two colors with "the same lightness" often aren't — which is why palettes drift into mud or vibration. In OKLCH, equal L means perceptually equal weight. Build a palette by holding L steady and varying H; everything stays balanced automatically.

The recipe

  1. Ground: base-100 at L 0.94–0.98 (light) or 0.15–0.20 (dark). Give it a whisper of chroma (0.005–0.02) — pure gray reads dead, slightly warm/cool gray reads intentional.
  2. Structure: base-200/base-300 same hue, L steps of 0.04–0.06. In dark themes, higher elevation = lighter surface.
  3. Ink: base-content shares the ground hue, L ≥ 0.9 (on dark) or ≤ 0.25 (on light).
  4. Accent: primary at C 0.12–0.20. Below 0.10 reads washed; above 0.22 vibrates uncomfortably except in playful registers.
  5. Content pairs: every -content must clear WCAG AA against its parent. Test pairs, not colors in isolation.

Dark-mode specifics

  • Include color-scheme: dark — browser chrome depends on it.
  • Desaturate semantic colors slightly (C −0.02); full-chroma neon on dark grounds hurts.
  • Shadows barely register on dark — borders do the separating.
  • Never flip to pure black (#000); L 0.15–0.17 keeps depth perception working.

Contrast quick-reference

Text Ground Minimum ratio
Body any 4.5:1
Large (≥24px or 19px bold) any 3:1
UI components/borders adjacent 3:1

Compute real ratios from OKLCH with any converter — but as a rule of thumb, ΔL ≥ 0.55 between text and ground clears AA comfortably.

Anti-patterns

  • Five accents "for variety" — dilution, not richness.
  • Chroma on structural surfaces (keep base-* near-neutral).
  • Same accent for links AND errors AND branding — meaning needs separation.