CSS LCH colors

I have always been interested in the science of color. In 2014, I spoke at various conferences, talking about the CSS Color 4 specification. Before that, in 2009, I wrote a program for choosing colors. She used a hidden Java applet to support ICC color profiles and to work properly with CMYK. It was, as far as I know, the first program of its kind. I never released it, but it led to the publication of this publication. Interest in color brought me to the man who became my husband. In 2019, I became the co-editor of the CSS Color 5 specification . My goal is to concretize my proposal.



color modification, which aims to allow designers to arbitrarily customize color channels to create color options. I also want to combine my offer with this offer. CSS LCH colors are something that really fascinate me. I am deeply convinced that designers, when they learn more about LCH colors, will be outraged by the fact that they still do not have the opportunity to use such colors.

What is LCH?


The CSS Color 4 module has, among other things, a definition of LCH colors . Today, all major browsers have either begun to implement their support, or are seriously considering this possibility:

  • In Safari support LCH is already being implemented.
  • This feature is expected in Chrome .
  • The possibility of implementing this feature in Firefox is discussed .

LCH is a color space that has some advantages over the RGB / HSL color spaces that everyone is used to working with CSS. In fact, I would go even further and call LCH a technology that can dramatically change the way colors work on the web. Here are three facts that allow me to make such statements.

▍1. LCH, compared to sRGB, gives access to about 50% more colors


This is a huge step forward. Right now, any CSS color we can set is defined in the sRGB color space . A few years ago, this was more than enough, since all monitors, except for professional ones, had a color gamut less than sRGB. However, now everything is no longer so. Today, the color gamut (that is, the range of colors that can be displayed) of most monitors is close to P3 . And the volume of this color space is 50% morethan the amount of space sRGB. CSS currently has absolutely no access to these colors. Let me repeat this: we do not have access to a third of the colors that modern monitors can display. And it's not about some minor colors. We are talking about the most vivid colors that monitors can display. Our sites look pale due to the fact that monitor hardware is evolving faster than CSS specifications and browser implementations.


Color Space sRGB and P3

▍2. LCH (and Lab) are color spaces uniform in perception


When working with LCH, the same numerical change in the color space gives the same perceived difference between colors. This property of color space is called “perceptual uniformity”. RGB or HSL color spaces are not uniform in perception. Here is a very revealing example of this feature ( here is the source of this example).


Heterogeneity of perception of HSL colors.

Colors in the upper and lower rows differ in tone by 20 degrees. Do you think the perceived difference between these colors is the same?

▍3. Brightness in LCH is an indicator that means something


In the HSL color space, lightness is a meaningless indicator. Colors may have the same lightness, but vary greatly in their perceived brightness. My favorite example is a comparison of yellow and blue. You may not believe me, but the colors shown below have the same HSL lightness.


HSL colors having the same lightness

Both colors have a lightness of 50%, but they certainly do not have the same perceived brightness at all. What is the meaning of the concept of "lightness" in HSL?

Here you can enter into a dispute with me, saying that lightness, at least, makes some sense with the same color tone (hue) and color saturation. That is - when changing lightness within the same color. And the truth: increasing HSL-lightness we get a lighter color, and decreasing - a darker color. But what happens will not necessarily be the same color.


Adjusting lightness with constant color tone and color saturation

Both of these colors have the same hue and the same saturation, but do they look like a darker and lighter version of the same color?

When using the LCH color model, colors having the same luminosity are perceived as colors having the same brightness, and colors with the same color are perceived as colors of the same saturation.

How are LCH colors arranged?


LCH is short for Lightness, Chroma, Hue (lightness, color, tone). The color components in this color model have some relation to the components of the HSL color model. But there are serious differences between the components of these color models.

The pitch angles in the LCH do not quite match the HSL tones. That is - 0 - this is not completely red. This color is rather closer to magenta. And 180 is not a turquoise color, it is rather blue-greenish, and it is completely complementary.


Colors with the same perceived brightness

Note that these colors, although very different in tone, look like colors that have the same perceived brightness.

In the HSL color space, saturation is represented by a neat range of values ​​from 0-100. The fact is that this space is the result of a simple transformation of RGB into polar coordinates. In LCH, however, the value of the chroma component is theoretically unlimited. The LCH standard (like Lab) is designed to be able to represent the full range of colors perceived by humans. Not all of these colors can be displayed on the monitor, even one that supports the P3 color space. Moreover, we are talking not only about the maximum number of displayed colors, depending on the color gamut of the monitor, but also about the difference in colors.

Perhaps this idea will be easier to understand if I illustrate it with an example. For the sake of simplicity, let's imagine that we have a monitor whose color gamut exactly matches the sRGB color space. For comparison, the 2013 MacBook Air screen could output about 60% sRGB, but most modern displays can, as already mentioned, display 150% sRGB. For L = 50 and H = 180 (the Cyan sample in the above figure), the maximum value of C is only 35! For L = 50 and H = 0 (Pink), the value of C can reach 77 without going beyond sRGB. For L = 50 and H = 320 (Purple), the value of C can go up to 108!

Although the lack of borders can be perceived as something frightening (whether it is about people or color spaces), there is nothing to worry about: if a color is set that cannot be displayed on a certain monitor, it will be reduced to a similar color supported by the monitor. In the end, there is nothing new: until the monitors acquired a color gamut that exceeded the capabilities of sRGB, this was exactly what happened with the usual CSS colors displayed on monitors whose color gamut was less than sRGB.

LCH color picker


I hope that now you are also a little interested in the idea of ​​using LCH colors. This raises the question of how to visualize these colors.

In fact, I quite a long time ago created the corresponding tool, LCH Color Picker, designed primarily to help me and my colleagues properly understand LCH features when editing CSS Color 5 . One is to know the theory, and quite another is to be able to experiment with the sliders and see the result with your own eyes. I even bought a domain, css.land , to post relevant examples there. We used this tool a bit, I added new features to it, but I never wrote about it. Therefore, this tool was available only to us, and to those who paid attention tothis github repository.


Means for selecting LCH colors

If you are interested in experimenting with LCH colors, you can very well use this tool. Here are some details about him:

  • The color conversion code was written by one of our team members. We are confident that the calculations, at least, were done on the basis of a correct understanding of the conversion process (that is, if something goes wrong - this is a mistake in the code, and not the result of a misunderstanding of something).
  • The Chroma color component supports a change in a range other than 0 - 100, which distinguishes our tool from some of the others that we were able to find.
  • Users can load arbitrary CSS colors into it (using the Import button).
  • The sliders allow you to enter only integer values, but in the black fields that appear above the sliders, you can enter any numbers.
  • In the process, you can save colors and see how they are interpolated.
  • Color analysis is supported for whether it belongs to the sRGB, P3 color space (or to Rec.2020, even a more extensive color space).
  • Supported transparency setting.
  • And finally, using this tool is simply interesting! Especially considering that it is implemented on the basis of Mavo (although a bit of JavaScript is used here, that is, it is not a Mavo project created in pure HTML).

As a matter of fact, you can try out the LCH Color Picker here .

Questions and answers


After I published this article, they started asking me questions. I believe that I should clarify here some common misconceptions.

▍You say that support for LCH colors in browsers is not yet implemented, but I can see them in the article. How is this possible?


All colors used in this article fall within the sRGB color gamut. This is because we simply cannot output colors outside sRGB so far. sRGB is a color space, not a color description syntax. For example, rgb(255 0 0)they lch(54.292% 106.839 40.853)set the same color.

▍How does the LCH Color Picker display colors outside sRGB?


My program, LCH Color Picker, does not display such colors. And, as far as I know, nowhere on the Internet is there a program that can display such colors. The LCH Color Picker project is implemented using web technologies, which means that the standard restrictions apply to any other web pages. I convert non-output colors to sRGB. At first, I simply brought the RGB color components to the range of 0-100%, but thanks to this PR , the program now uses a much more successful algorithm. Namely, we are talking about reducing the value of the LCH component C until the color falls within the sRGB limits. That is why an increase in the value of component C above a certain limit does not lead to the conclusion of a brighter color. The fact is that such a color cannot yet be deduced using CSS.

▍ I noticed that Firefox displays brighter colors than Chrome and Safari. Is there any connection with LCH support?


Firefox has not implemented that part of the specification that restricts CSS colors to sRGB frames. Instead, the browser simply passes raw RGB values ​​to the screen. For example, rgb(100% 0% 0%)this is the brightest red color that a monitor can display. Although this may seem like a smart solution, here we are faced with contradictions. The fact is that with this approach, you can set colors, at best, only approximately, since all screens display colors differently. By restricting CSS colors to a known color space (sRGB), we get device independence. The LCH and Lab color spaces are also device independent, as they are based on actual measured color.

▍ What can you say about the color (display-p3 rgb) design? Safari has been supporting it since 2017!


I was informed about this after I published this article. I have long known that Safari is working on this feature, but somehow I missed the moment when it was ready. In fact, last month this article was published describing this syntax in WebKit. Amazing

Design color(colorspaceid params)is a feature described in CSS Color 4. Her, in the matter of color management in CSS, can be compared with a Swiss knife. The great thing about this design is that it allows you to specify the ICC color profile and the colors taken from it. For example, this can be useful if you want to use real CMYK colors or Pantone colors on a web page. This design also supports some predefined color spaces, one of which is display-p3. For example, color(display-p3 0 1 0)it gives us the lightest green color in the P3 color space. To test support for this design, you can use this test. In the absence of support color(), a red color will be shown, and if available, a light green color.

Although this is an amazing feature (and I need to remake my LCH Color Picker so that the program would use it color()if this feature is supported), pay attention to the fact that it solves only the first of the problems I have mentioned. Namely, we are talking about access to all colors from the color gamut. But, since the tool is color()based on RGB, it suffers from all the disadvantages associated with RGB. It is not distinguished by a uniform perception, with its help, by adjusting the color parameters, it is difficult to create color options (lighter or darker options, more or less bright, and so on).

Moreover, I note that this is a temporary solution. Now it is applicable due to the fact that screens that can display colors that do not fit in P3 are rare. But after another improvement of the displays, it turns out that the design color(display-p3 ...)will have the same problems that RGB-colors now have.

The color spaces LCH and Lab are device independent, they can represent all the colors that are visible to humans, and as a result they will remain relevant regardless of the evolution of hardware.

Dear readers! Are you interested in using LCH colors in CSS?


All Articles