oklch() retains perceived lightness for different hue angles
- Published at
- Updated at
- Reading time
- 3min
As far as I see, it's time to ditch hsl()
and use oklch()
for color palettes and design systems. Why's that?
For me, it boils down to two reasons.
New devices and monitors can display colors that aren't defined in the sRGB color space used by rgb()
, hsl()
or hex colors. Isn't it sad that you can't express these vibrant colors in CSS using existing color methods?
It is. And the solution are new CSS color functions that can talk new and fancy monitor tech (namely wide-gamut P3 colors). It's party time y'all โ the web gets a color update with fresh and vibrant colors.
There's oklch()
, oklab()
and also color()
to target the wider color space, but let's focus on oklch()
because it's the most user-friendly.
oklch()
's parameters (lightness, chroma and hue) are easy to grasp and feel very similar to hsl()
(although chroma and saturation are two pair of shoes).
But coming back to the wider color space, if you want to see them in action with oklch()
, oklch.com from the Evil Martians is the place to go. You can inspect and convert colors from and to oklch()
. Unfortunately, neither my external display nor my old MacBook can display P3 colors, but if you're on recent hardware, you might see very vibrant colors on the site.
And while vibrant colors are already a good reason for ditching hsl()
in favor of oklch()
, another reason outweighs the funky colors.
As already mentioned, the lch
in oklch()
stands for lightness, chroma and hue. And if you now modify the hue angle of oklch()
colors, they keep their perceived lightness.
Can that be true? I had to see if this holds. And here's my investigation.
Change the hue angle of these almost identical colors, and see that a hsl()
color can drastically change its lightness, while the oklch()
color stays almost the same.
And to prove the point, here's a color palette rotating hue angles of hsl()
and oklch()
colors...
hsl()
oklch()
... and here are two CSS color gradients spanning a 180 degree hue angle.
hsl()
oklch()
A 45 degree hue change can sometimes lead to very different colors depending on the color function. And these differences are fine.
But it's not cool that hsl()
colors change their perceived lightness when you rotate the hue angle. An hsl()
blue with the same saturation and lightness is much darker than a yellow. You can't just change a blue card component to a red one and expect that text stays readable. Booh! ๐
oklch()
colors, on the other hand, retain their lightness. A blue with the same lightness and chroma feels as light as a yellow. You can trust the color function not to make colors much lighter or darker. Yay! ๐
And to prove the point, if you then turn on the grayscale, you'll see that oklch()
colors with similar lightness and chroma values stay almost on the same gray tone. They're not changing in perceived lightness. Fancy!
So in summary, when you need to manipulate colors and want to avoid color contrast issues, oklch()
is your friend from now on!
But can you use it today? Absolutely.
111 | 111 | 111 | 113 | 113 | 15.4 | 15.4 | 22.0 | 111 |
Have fun coloring!
Join 5.5k readers and learn something new every week with Web Weekly.