Two Things That are Not Great About OKLCH

I’m still a fan of the OKLCH color model and CSS function. But there are a couple of things that are confusing or weak about it, and it’s probably fair to point those out clearly.

1) Adjusting the L, C, and H values by hand is a bit dangerous

Dangerous because of totally invalid combinations. Here’s an example.

I’ve got this perfectly normal green color:

.el {
  border-color: oklch(68% 0.25 150);
}Code language: CSS (css)

Well, I know that 68% is the Lightness, 0.25 is the Chroma (sorta like saturation), and 150 is the Hue. Hue, like many of these color models, goes from 0 to 360. Increasing the Hue from the 140 where it’s at which is in Green-land should push it into Blue-land, then Purple-land, and Pink-land, then Red-land as it approaches 360.

If I just push that 150 Hue to 152… well… the color picker at will tell you that that color doesn’t exist. And I guess it kind of doesn’t. Those numbers have left the P3 color space. Does that make the color “invalid”? I… don’t know. I don’t have the language for that. In the originally published draft of this post, I assumed it was invalid and would render as nothing. But, I guess you could call it good news, the specced behavior is that colors with values outside the space (and/or model?) get brought back in, so colors will never render as blank nothing. Probably smart, and good that it’s specced, but feels awfully strange to me to be picking essentially coordinates of colors that don’t exist. And then if you do that, do you still get the correct behavior of the model, like consistent lightness and all that? So much to know.

Those big empty gaps in the color space? That’s intentional! That’s part of the design of the color space. It’s like that because it actually solves some problems, like uniform brightness. But it causes others, like quite a few number combinations having this “invalid and thus must be mathed-into-place” problem. Which is usually called “clipping” I think, but I also have heard that behavior is controversial.

You can see this pretty clearly in the 3D model of the color space:

In the sRGB color space that we’re mostly used to, well, it’s a cube, so there aren’t really “invalid” values unless you do something intentionally weird and out-of-bounds.

The programmatic champion that is HSL is within the RGB color space but is modeled like a cylinder, making it similarly difficult to make a “wrong” combination.

In rgb(), there is no “wrong” value of r, g, or b, as long as it is 0 to 255. In hsl(), there is no “wrong” value of h, s, or l, as long as it’s between 0 and 255 for the hue and 0% and 100% for the saturation and lightness. It’s no wonder why CSS adopted those models… they are just easier to reason about.

I tell you what though, color me (lol) interested in Okhsl, which seems to be a model where uniform brightness while maintaining the easy and predictable numbers of the HSL model.

2) Gradients have super awkward combinations like any other color space

I messed around with Adam’s Pen and got this.

I thought that OKLCH was supposed to be a majorly clear winner with interpolating gradients, but I’m not so sure. It’s true that it generally avoids “the gray dead zone”, but sometimes it does so by travelling through some other very unexpected color territories. More vibrant? Usually. More intuitive? Nope.

The syntax for interpolating in a particular color model is:

.el {
  background: linear-gradient(
    to right in oklch,
}Code language: CSS (css)

So I think the answer for really nice gradients going forward is either:

  1. Pick the color model that has the best results using the syntax above, or…
  2. Use a whole bunch of color stops so the path the colors take along the way is predictable.
  3. Use OKLAB as apparently it’s the most generically best at this job.


I work on CodePen! I'd highly suggest you have a PRO account on CodePen, as it buys you private Pens, media uploads, realtime collaboration, and more.

Get CodePen Pro

7 responses to “Two Things That are Not Great About OKLCH”

  1. For gradients, it is better to use Oklab, than OKLCH.

    Oklab is pretty good as default for gradients.

  2. Chris Lilley says:

    If I just push that 150 Hue to 152… dead. I have now left the P3 color space and the color is totally invalid and will render as nothing.

    This is completely untrue (both that it is invalid, and also that it will render “as nothing”). Can you point to some specification text that leads you to this conclusion?

  3. JD Solanki says:

    “Adjusting the L, C, and H values by hand is a bit dangerous”. Does this mean If I want to add some lightness to the color on hover state using color-mix, it’s dangerous and might give invalid or weird color?

    • Chris Coyier says:

      To me, at first, it seemed like there are lightness values that are “invalid”, but apparently that’s entirely not the case and there are clipping or correcting mechanisms in place in the spec that pull the values back in and display the closest most appropriate color. Is it possible the result is weird? I think it is, I’ve now seen some cross-browser-different clipping results, but it’s probably not a wildly huge problem.

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to Top ⬆️