OKLCH Color Space: Perceptual Uniformity & Display P3
- Last updated
- Prerequisites:
- CSS colors (hex, rgb, hsl)
- Understanding of color models and the sRGB gamut
- css
- color
- oklch
- color-space
- display-p3
- wide-gamut
Read at your depth
The practical view
oklch() is a color function with three channels: lightness (L), chroma (C — how vivid), and hue (H — the color angle). background: oklch(70% 0.15 250);. Unlike hex/hsl, oklch is perceptually uniform: equal numeric steps look like equal visual steps. To make a palette, keep L constant and rotate H, or keep H constant and step C. It also exposes colors outside sRGB: you can specify wide-gamut colors for Display P3 screens (use color(display-p3 r g b) or just oklch values that exceed sRGB chroma), letting high-end monitors show richer colors with graceful fallback.
The same idea in other frameworks
Design-token systems in React apps (Tailwind v4, CSS vars) increasingly use oklch for theme ramps and interpolation.Angular Material's color palettes can be regenerated in oklch for perceptual spacing between tones.Vue apps using CSS variables for theming benefit from oklch tokens that interpolate predictably.SvelteKit sites with CSS variable themes can adopt oklch tokens for consistent dark/light ramps.Legacy vs modern
HSL hand-tuned palette vs OKLCH generated palette
HSL lightness is not perceptually uniform — equal steps look uneven; OKLCH lightness steps look visually even, so palettes are predictable.
--c-500: hsl(210 80% 50%); /* ❌ OLD: equal lightness steps do NOT look even */--c-500: oklch(55% 0.16 250); /* ✅ NEW: even perceptual steps */Interview gotchas
Context
This tests whether you understand perceptual uniformity — the actual math behind why HSL ramps look uneven — rather than just repeating 'OKLCH is modern'.
The mechanical answer
HSL's lightness channel is a simple model that does not match human perception: two colors with the same HSL lightness can appear very different in brightness, and equal lightness steps look uneven (especially in the mid-tones and for saturated colors). Interpolating in HSL between two colors passes through desaturated grey midpoints because hue and saturation are treated as a naive cylinder. OKLCH is built on a perceptually-uniform model (CAM16-UCS-derived): equal numeric steps in L correspond to equal perceived lightness differences, and chroma/hue interpolation keeps colors vivid through the whole gradient. This makes generated ramps and gradients predictable and consistent, which is why design systems have migrated to it.
Trap
The naive answer is 'OKLCH just has nicer color names or more channels'. The difference is the perceptual model behind the numbers. Another trap: assuming any color space interpolates identically — color-mix(in hsl, ...) vs color-mix(in oklch, ...) produce visibly different gradients, and the in-hsl one muddies. Candidates who mention perceptual uniformity and interpolation space selection show real understanding.
Context
This probes the wide-gamut story — that oklch values can encode colors outside sRGB, and how the browser handles out-of-gamut values on both wide and standard displays.
The mechanical answer
OKLCH is a color space, not a gamut: its L and C channels can express colors beyond the sRGB gamut, particularly high-chroma colors that fit in Display P3. On a wide-gamut (P3) display, the browser converts the oklch value through the color pipeline and renders the extra saturation; on an sRGB display, the value is gamut-mapped to the closest reproducible color. The CSS Color 4 spec mandates gamut mapping (not naive clipping) — it preserves hue and lightness while reducing chroma, avoiding ugly hue shifts. You can also write color(display-p3 ...) to target P3 directly. For wide-gamut delivery, serve P3 values via @supports or use oklch values whose chroma naturally exceeds sRGB, letting browsers handle conversion.
Trap
The naive answer is 'oklch automatically makes colors brighter on every screen'. On sRGB displays the extra chroma is gamut-mapped down; the benefit only materializes on wide-gamut hardware. Another trap: thinking hex and oklch(0.5) with high chroma are interchangeable — hex is sRGB-only and cannot express the wide-gamut colors oklch can. Candidates who explain gamut mapping vs clipping and the P3 target show real depth.