Docs/THEMING/OKLCH Colors

OKLCH Colors

GwenUI uses OKLCH — a perceptually uniform color space that produces consistent contrast ratios across all hues.

Why OKLCH?#

Most design systems use HSL or HEX for colors. GwenUI uses OKLCH for all tokens.

The difference matters: in HSL, two colors at the same lightness value can appear visually very different in brightness. OKLCH is perceptually uniform — the same lightness value always produces the same perceived brightness, regardless of hue.

/* HSL — same lightness, wildly different perceived brightness */
hsl(60 80% 50%)   /* yellow — looks very bright */
hsl(240 80% 50%)  /* blue — looks much darker */
 
/* OKLCH — same lightness, consistent perceived brightness */
oklch(60% 0.18 60)   /* yellow-orange */
oklch(60% 0.18 240)  /* blue */
/* Both appear the same brightness ✅ */

OKLCH syntax#

oklch(L C H / A)
ParameterRangeDescription
L (Lightness)0%100%Perceived brightness
C (Chroma)00.4Color saturation/intensity
H (Hue)0360Color wheel angle
A (Alpha)01Opacity (optional)

GwenUI primary color anatomy#

--primary: oklch(68% 0.18 48);
/*                ↑    ↑   ↑
                  │    │   └── Hue 48 = orange-amber
                  │    └────── Chroma 0.18 = vivid but not harsh
                  └─────────── Lightness 68% = bright, accessible on dark bg

Browser support#

OKLCH is supported in all modern browsers:

BrowserSupport
Chrome 111+
Firefox 113+
Safari 15.4+
Edge 111+

For older browser support, use a PostCSS plugin like postcss-oklch to convert OKLCH values to HSL fallbacks at build time.

Creating custom colors#

When creating custom tokens, use OKLCH to maintain perceptual consistency:

:root {
  /* Custom accent — same lightness as --primary for visual harmony */
  --accent: oklch(68% 0.18 200);  /* teal, same brightness as orange primary */
}

Keep chroma between 0.1 and 0.25 for UI colors — above 0.3 can exceed the sRGB gamut on some displays.

Tools#