hsl() in CSS is fairly popular because of how sensical it is. Hue, saturation, and lightness.
hsl(260, 85%, 50%)
260 is bluey-purple territory. 85% means pretty thickly saturated. 50% is right in the middle of lightness, not toward a blackening or whitening.
And with sensible numbers like that, you can perform math the color and feel good about it. Change the hue to find a green that feels related to this purple. Make a lighter version by changing the lightness. Nice.
But there is trouble.
In HSL, lightness is meaningless. Colors can have the same lightness value, with wildly different perceptual lightness.Lea Verou, co-creator of the new Color.js library, explaining the main problem with HSL and introducing LCH.
LCH is just one of many new color features that have made way to the web recently. They are all neat, but it feels to me LCH is the biggest winner.
Look how similar it is to HSL. Feels like basically the same thing to me, except:
- It’s one of the new color space thingies that unlocks colors we haven’t been able to show on the web before. Score!
- Interpolating between colors (i.e. gradients) yields nicer results. No gray dead zone! Score!
- It has consistent perceptual lightness, meaning colors with the same lightness actually feel like the same lightness. Score!
The image above is from the article LCH is the best color space! by Vojtěch Vidra and Ondřej Pešička who say LCH is the best for color palletes. I tend to agree. None of the other formats that have similar benefits have that human-readable syntax or open the same doors for very simple code-powered manipulation.
LCH has a big problem. It has a hue shift on chroma change in blue.
OKLCH is a fix for LCH, and it is also in CSS Colors 4. oklch() support is pretty equal to lch() support.
Also, OKLCH has a few small improvements. For instance, gammut mapping (map P3 colors to sRGB) is faster and simpler.
Sounds like OKLCH is better in several ways (I wonder if it’s worse in anything? Perhaps a particular gradient or something?), so should probably be used instead. One way it definitely seems worse is the name. Seems like it will almost certainly limit adoption and cause weird fragmentation. Like if instead of making the flexbox spec/implementation better, the improvements were shipped as