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.

ModelComponentsUnderlying idea
HSLHue, saturation, lightnessA geometric transformation of sRGB values
OKLCHPerceptual lightness, chroma, hueA 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.

Test the actual devices you support.Do not assume that a mathematically valid OKLCH value will appear identical on every display. Keep an sRGB fallback when your compatibility policy requires one.
.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
Check a color pairGenerate an OKLCH-based paletteReview color formats

A sensible production workflow

  1. Accept familiar inputs.Let users enter hex, RGB, or HSL when that is the easiest source.
  2. Convert to a perceptual space for system work.Use OKLCH or OKLab to generate scales, harmonies, and transitions.
  3. Control chroma at the extremes.Reduce it for very light and very dark steps.
  4. Check gamut.Decide whether to clip to sRGB, support wide gamut, or provide both.
  5. Test contrast on rendered values.Do not infer accessibility from color-space coordinates.
  6. Export with fallbacks when necessary.Match the browser and platform support policy of the product.
Use HSL for convenience and OKLCH for structure.That is not a universal law, but it is a strong default for modern design-system work.

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.