Modern Color Spaces: oklch and oklab
- CSS Basics
- Selectors & Specificity
- Box Model & Units
- Typography & Text Styling
- Colors & Color Spaces
- Positioning & Stacking Context
- Flexbox
- Grid
- Grid Advanced
- Responsive Design
- Container Queries
- Pseudo-classes & Pseudo-elements
- Modern Selectors
- CSS Custom Properties
- CSS Functions
- Transitions & Animations
- Transforms
- Forms & Input Styling
- CSS Architecture & Methodologies
- Accessibility in CSS
- Performance & Optimization
- View Transitions & Modern APIs
- Cascade Layers & Scope
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.