oklch() retains perceived lightness for different hue angles
- Published at
- Updated at
- Reading time
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
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.
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
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.
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.
Have fun coloring!