Get affordable and hassle-free WordPress hosting plans with Cloudways — start your free trial today.
The lch()
color function specifies colors in the CIELAB color space. Unlike the lab()
function — which uses Cartesian coordinates — the lch()
function uses polar coordinates to set color in terms of its hue and chroma/saturation, which is generally more intuitive.
.element {
color: lch(10% 0.215 15deg);
}
The function is a big improvement from the rgb()
and hsl()
functions because the CIELAB color space it uses is larger than the sRGB color space used by those other functions, representing a larger range of color.
The lch()
color function is defined in the CSS Color Module Level 4 and Level 5 specifications.
Syntax
Just like lab()
, lch()
can only be written as a space-separated list, so use spaces, not commas.
lch( [<percentage> | <number> | none]
[ <percentage> | <number> | none]
[ <hue> | none]
[ / [<alpha-value> | none] ]? )
Arguments
/* Percentages from 0% - 100% for the L value */
.element {
color: lch(40% 20 10deg);
}
/* Numbers from 0.0 - 100.0 for the L value */
.element {
color: lch(10.67 40 40deg);
}
/* Percentages from 0% - 100% for the C value */
.element {
color: lch(40.6 30% 40deg);
}
/* Numbers from 0.0 - 150.0 for the C value */
.element {
color: lch(10.5 120 50deg);
}
/* Angles from 0deg - 360deg for the H value */
.element {
color: lch(30.6 100 30deg);
}
/* Numbers from 0 - 360 for the H value */
.element {
color: lch(50.12 49 140);
}
/* Numbers from 0% - 100% and 0 - 1 for the transparency value */
.element {
background-color: lch(40 10 20 / 50%);
color: lch(70 32 13 / 0.5);
}
l
: Sets lightness and ranges from0%-100%
or0-100
. where0%
is completely dark and100%
is completely light.c
: Sets the color’s chroma (which is like saturation), and ranges between0%-100%
or0-150
. Chroma sets how pure a hue color is before being diluted with white or black.h
: Sets the color hue. It can be either a number or an angle between0deg-360deg
. Angles are cyclic for each360deg
, so0deg
,360deg
,720deg
, etc. are the same, and going over360deg
is just like starting the hue from zero.<alpha-value>
: Sets the transparency and can be any decimal value between0
to1.0
(e.g. 0.85) or any percentage from0%
and100%
.
lch()
Understanding The lch()
and lab()
functions are compatible with colors defined in the CIELAB color space, which is designed to represent the entire color range that is visible to the human eye. CIELAB uses three axes to represent color: one lightness axis that sets the amount of white and black, and two color axes that set the amount of green-to-red and yellow-to-blue in the color. Knowing this, we can think of the CIELAB color space as a 3D plane in which each point represents a color.
Due to screen limitations, most displays cannot represent most of the colors represented by lch()
and lab()
.
Both lab()
and lch()
live in the same 3D plane and use the same notation to set their lightness, with the key difference being how they move around their color axes. While lab()
takes the Cartesian coordinates of the color, that is, setting the color’s position on each axis, lch()
uses the Polar coordinates of the color, which is a fsncy way of saying it uses an angle (hue
) and the distance from the center (chroma
) to choose a point.

Image from Kwality Labels
Anything related to chroma and hue makes it easier for designers and developers to use, allowing everyone to use more colors and move away from sRGB, which can only access one-third of colors available on most modern screens.
One thing to note is that the more chroma, the more vivid the color looks. With a high chroma, you can have the reddest of a red color, but with a low chroma, it may look dull. I know it sounds like low chroma is bad, but it’s useful if you want your text or other colors on your page to “pop out” more than the rest.
You may be asking yourself if lch()
is better to use than lab()
?” My answer is yes. It is generally considered better than lab()
because of its polar coordinate system, making it more intuitive, the same way that writing colors in the sRGB color space with the hsl()
function is easier to write and understand than using rgb()
. For example, reading each lab()
value is not as easy as you may think. I cannot simply guess this color from a glance:
.element {
color: lab(14 96 93);
}
I know the color’s position on each axis, but what does this even mean? In the case of lch()
I know how vivid my red will be or whether my color is pink just by reading its chroma and hue values.
.element {
color: lch(60 58.3 301deg);
}
Let’s walk through the value above together. The lightness is set to 60
, so we know it is relatively bright. We set our chroma to 58.3
which is moderately saturated, and then we set our angle to 301deg
, so it’s a color between blue and red. Then we can say our color will have a moderately vivid purple-blueish vibe! Yay! That was somewhat easy.
Even though both lab()
and lch()
were created to capture the colors of the human vision, I would say that lch()
is more intuitive and easier to understand than lab()
.
Basic usage
To recap, lch()
has three main arguments in a space-separated list. First, l
sets the lightness ranging from 0
to 100
, then c
sets the chroma value from 0
to 150
, and lastly h
rotates the hue to select different colors from 0deg
to 360deg
. And if you need to adjust the color’s transparency, you can write a forward slash (/
) followed by the transparency value as either a decimal between 0
to 1
or as a percentage between 0%
and 100%
.
.element {
color: lch(40 50 40deg / 75%); /* or lch(40 50 40deg / .75); */
}
Relative colors
The CSS lch()
function supports the relative color syntax, so we can convert a color from one color space into another color in another color space.
.element {
color: lch(from hsl(10% 20% 90%) l 40 150deg);
}
To use it, you need to include the from
keyword followed by any color (it can be another color function or a named color), then replace any of its values with its corresponding channel letter (in this case, l
for lightness, c
for the chroma value, h
for the hue color, and the optional alpha
for the alpha value), and they will take on the value from the original color.
A quick demo below shows the colors produced by rgb()
inside lch()
:
.element {
background-color: lch(from rgb(250, 170, 155) l c h);
}
And the other way around, we can translate lch()
, which operates in the CIELCH color space, to the sRGB color space to be used by sRGB-based functions rgb()
, hsl()
or hwb()
.
lch()
Color gradients with Like lab(), lch()
looks more beautiful and vibrant, and represents corners of the CIELCH color space that hsl()
and rgb()
could ever dream of. One specific case further proves this: gradients.
Without getting too detailed, let’s make two gradients from colors in sRGB using rgb()
and hsl()
and compare it to another gradient in CIELCH using the lch()
function:
See the difference? Just like lab()
, lch()
is brighter and more vibrant than hsl()
and rgb()
. Some may even say they look “washed”, especially when passing through sRGB’s dead gray zone, which is caused by the lack of access to more color.
lch()
Math functions can be used in You can use math functions in hsl()
to manipulate a color stored in a custom property:
.element {
background-color: lch(
calc(var(--my-l-value) + 10) calc(var(--my-c-value) + 50) var(--my-h-value) / calc(var(--my-alpha-value) + 0.1)
);
}
It can even be used to change each channel after using the relative color syntax:
.element {
background-color: lch(from hsl(150deg 70 20%) calc(l + 20) calc(c + 30) h);
}
In the example above, I’m using the calc()
function to add 20 more points to the l
channel and 30 more to the c
channel. Here’s what this looks like in the demo below:
Demo
Here’s a demo showing how the lch()
function works with a conic gradient. Change the values to update the color scheme and see how each value influences the overall color:
Specification
The lch()
function is defined in the CSS Color Module Level 4 specification, while the relative syntax using channel letters is defined in the CSS Color Module Level 5 specification. Both are currently in Editor’s Draft status at the time of writing. This means changes can still be made to this function in the future.
Browser Support
More information
- Color Science Explained: Lab and LCH Color (Kwality Labels)
- Colour: Value, Chroma and Temperature (Sophie Ploeg)
- A Guide To Modern CSS Colors With RGB, HSL, HWB, LAB And LCH (Michelle Barker)
- Should we ditch Lab colors and fall in love with LCh? (Eddy Hagen)
- LCH colors in CSS: what, why, and how? (Lea Verou)