OKLCH converter and palette builder

Convert between OKLCH, hex, RGB and HSL, and build ramps that stay perceptually even because lightness and chroma are held while hue moves. Colours outside sRGB are mapped by reducing chroma, not by clipping — the difference is whether your purple stays purple.

Hex, rgb(), hsl() or oklch().

    

Why lightness in OKLCH means something

In HSL, changing the hue at fixed lightness changes how bright the colour looks: yellow at 50% reads far brighter than blue at 50%, which is why HSL ramps look uneven no matter how carefully you space them. OKLab was fitted to perceptual data, so its lightness axis tracks what the eye reports. Hold L and C and rotate H and every swatch carries the same visual weight — which is the whole reason to build palettes here rather than in HSL.

Gamut mapping is the part that matters

Plenty of OKLCH values have no sRGB equivalent, and the naive fix is to clamp each channel into range. That shifts hue visibly: a vivid purple clipped channel by channel drifts towards blue. Reducing chroma while holding lightness and hue keeps the colour recognisably itself and only takes away the saturation the screen could not show. This page uses the algorithm from CSS Color 4 — bisect on chroma, and accept a clipped result once it sits within a just-noticeable difference of the reduced one.

Checked against a reference

The conversions were compared with an independent implementation over a grid of four thousand colours: lightness and chroma agree to within a millionth, hue to a ten-thousandth of a degree, and every hex value round-trips exactly. The gamut mapping was checked the same way against four hundred and eighty out-of-gamut colours and lands within one part in 255 on the worst of them. An audience that reads OKLCH notices a wrong matrix, so it seemed worth saying how it was verified.

Using the output

The custom properties are written in OKLCH with the hex beside them in a comment, because that is the pair you want in review: the value your build ships and the value you can paste into anything else. Every browser in current use understands the OKLCH syntax; if you still support one that does not, the comment is your fallback.

FAQ

Why is chroma capped at 0.4?

Because nothing in sRGB gets near it. The most saturated sRGB colour is blue at about 0.313, and the slider goes past that so you can see what falls outside and how it maps back.

What is a just-noticeable difference here?

A delta E of 0.02 in OKLab, which is the threshold CSS Color 4 uses. Below it, clipping and chroma reduction are indistinguishable, so the algorithm takes the clipped colour and keeps the extra chroma.

Does it handle P3 or Rec2020?

Not yet. Everything here targets sRGB, which is what the gamut warnings mean. Wider gamuts need their own primaries and a second set of matrices.

Is any of this sent anywhere?

No. The conversions run in this page.

Built by the GO AI team. CSS clamp() calculator · All free tools