COLOR SPACES ยท CSS
OKLCH vs. HSL: which one should you use?
HSL is easy to read and widely understood. OKLCH makes lightness and colorfulness behave more like people expect. The better choice depends on whether you are entering a color, generating a system, or shipping production CSS.
They are not two notations for the same controls
HSL and OKLCH both present a hue angle, which makes them look similar. Their other components describe different things.
| Model | Components | Underlying idea |
|---|---|---|
| HSL | Hue, saturation, lightness | A geometric transformation of sRGB values |
| OKLCH | Perceptual lightness, chroma, hue | A polar form of OKLab designed around visual similarity |
That difference matters because an HSL lightness of 50% does not imply the same perceived brightness for blue, yellow, green, and red. OKLCH lightness is designed to be more visually consistent across hues.
Where HSL remains useful
HSL is convenient when people need to understand or edit a color quickly. The syntax maps cleanly to familiar words: rotate the hue, reduce saturation, or make the color lighter.
- Simple UI controls and educational tools
- Small one-off adjustments within an existing sRGB palette
- Legacy CSS systems and broad browser compatibility requirements
- Communicating approximate color intent with non-specialists
.button {
background: hsl(216 20% 59%);
}
.button:hover {
background: hsl(216 24% 52%);
}For a single component and a narrow range of changes, HSL can be perfectly practical.
Why HSL scales can look uneven
HSL lightness is derived from the highest and lowest sRGB channels. It is not a measurement of how bright a person perceives the result. This creates several common problems:
- A yellow and a blue with the same HSL lightness can look dramatically different in brightness.
- Equal lightness steps can produce uneven tonal scales.
- High saturation values do not represent equal colorfulness across hues.
- Changing hue while holding saturation and lightness can create unwanted contrast changes.
This is why a generated HSL scale may contain several middle values that look nearly identical while another part of the scale changes too abruptly.
Why OKLCH is better for systematic variation
OKLCH separates a perceptually oriented lightness value from chroma and hue. That makes it easier to create scales where each step feels intentional.
:root {
--brand-100: oklch(94% .03 255);
--brand-300: oklch(80% .07 255);
--brand-500: oklch(64% .11 255);
--brand-700: oklch(46% .09 255);
--brand-900: oklch(27% .05 255);
}The hue can remain stable while lightness and chroma are adjusted independently. In practice, a useful tonal scale usually reduces chroma near the lightest and darkest ends because extremely light or dark colors cannot carry as much visible colorfulness.
Better does not mean automatic
Equal OKLCH lightness steps are more perceptually consistent, but they still need design judgment. Surrounding colors, viewing conditions, text weight, and the area occupied by a color all affect the result.
OKLCH can describe colors outside sRGB
Hex and HSL describe sRGB colors. OKLCH can describe a broader range, including colors that some wide-gamut displays can show but ordinary sRGB displays cannot.
When an OKLCH value falls outside the available gamut, the browser must map it to a displayable result. That can reduce chroma or shift the appearance. A value that looks vivid on a Display P3 screen may look more restrained elsewhere.
.brand-surface {
background: #1b8e2d;
background: oklch(56% .16 145);
}Neither model guarantees accessible contrast
OKLCH lightness is useful for reasoning about a scale, but WCAG contrast uses relative luminance from the rendered colors. Two colors with separated OKLCH lightness values can still fail the required threshold.
Use the model to generate and tune colors, then check the exact pair in the context where it will appear. This is especially important for:
- Small or muted text
- Colored text on tinted surfaces
- Focus indicators and form boundaries
- Hover and disabled states
- Transparent overlays and gradients
A sensible production workflow
- Accept familiar inputs.Let users enter hex, RGB, or HSL when that is the easiest source.
- Convert to a perceptual space for system work.Use OKLCH or OKLab to generate scales, harmonies, and transitions.
- Control chroma at the extremes.Reduce it for very light and very dark steps.
- Check gamut.Decide whether to clip to sRGB, support wide gamut, or provide both.
- Test contrast on rendered values.Do not infer accessibility from color-space coordinates.
- Export with fallbacks when necessary.Match the browser and platform support policy of the product.
Specifications and further reading
The W3C CSS Color 4 HSL section defines HSL as an sRGB representation. The same specification defines OKLab and OKLCH, gamut mapping, and modern color interpolation.
GO DEEPER
The color science behind color spaces for design systems.
Move from practical CSS color controls into perceptual uniformity, color appearance, and visible color-difference limits.