Modern Color Spaces: oklch and oklab

A Gap in Older Color Formats

Hex, RGB and HSL are all built around how screens mix red, green and blue light, not around how the human eye actually perceives brightness. This means two colors with the "same" lightness value in HSL can look noticeably brighter or dimmer to the eye depending on their hue - blues often look darker than yellows at an identical HSL lightness.

What oklch Is

oklch() describes color using a perceptually uniform model: lightness, chroma (intensity) and hue. "Perceptually uniform" means that changing the lightness number by the same amount produces a change that looks equally different to a human eye, regardless of hue.

.box {
  background: oklch(70% 0.15 250); /* lightness, chroma, hue */
}

What oklab Is

oklab() uses the same underlying perceptual model as oklch, but describes the color with a lightness value plus two axes (green-red and blue-yellow) instead of chroma and hue. It is mainly used as the basis other functions (like oklch, and color interpolation) are built on top of.

Why This Matters in Practice

Because oklch is perceptually even, generating a consistent set of shades - for example five steps from light to dark for a design system - is far more reliable than doing the same math in HSL, where equal-looking steps in one hue can look uneven in another.

:root {
  --brand-100: oklch(95% 0.03 250);
  --brand-500: oklch(65% 0.15 250);
  --brand-900: oklch(30% 0.08 250);
}

A Practical Note

Both functions are supported in current major browsers. For projects that must support much older browsers, it is common to declare a hex or RGB fallback first, since a browser that does not understand oklch() will simply ignore that later declaration.

Written by Lorens Mishra

Software Engineer Notes Management System Administrator

Continue reading

All CSS notes →

Discussion

0 comments
Sign in to join the discussion.

No comments yet. Be the first to say something.