CSS lch() Function
The CSS lch() function defines colors using perceptual lightness, chroma, and hue in the CIE LCH color space.
It provides a way to adjust a color's lightness, intensity, and hue separately. LCH is based on the CIE Lab color space and can represent colors outside the standard sRGB gamut.
Syntax
lch(L C H)
lch(L C H / alpha)
lch(from color L C H)
lch(from color L C H / alpha)
The first three components define lightness, chroma, and hue. An optional fourth component specifies transparency.
For example:
.box {
background-color: lch(60% 50 40);
}
This defines a color with 60% perceptual lightness, a chroma value of 50, and a hue angle of 40 degrees.
Additional examples:
color: lch(0% 0 0);
color: lch(100% 0 0);
color: lch(60% 0 0);
color: lch(60% 30 40);
color: lch(60% 60 40);
color: lch(60% 60 180deg);
color: lch(60% 60 270deg / 50%);
color: lch(from red l c h);
Components are separated by spaces, not commas. Transparency is introduced using a forward slash.
The function returns a CSS <color> value.
Parameters
The lch() function accepts three required color components and an optional alpha component.
| Parameter | Description | Required |
|---|---|---|
L |
Perceptual lightness, where 0 represents black and 100 represents white. | Yes |
C |
Chroma, representing the distance from a neutral gray color. | Yes |
H |
Hue angle, determining the color direction. | Yes |
alpha |
Opacity of the color. | No |
from color |
Optional origin color used with relative color syntax. | No |
For example:
lch(65% 55 120 / 0.8)
This specifies 65% lightness, chroma 55, a hue of 120 degrees, and 80% opacity.
The lightness and chroma components accept numbers, percentages, or none. Hue accepts a number, angle, or none.
How It Works
The CIE LCH color space describes colors using polar coordinates derived from CIE Lab.
Each component controls a different aspect of the color:
Ldetermines perceptual lightness.Cdetermines how far the color is from neutral gray.Hdetermines the hue direction.
For example:
lch(60% 0 40)
lch(60% 30 40)
lch(60% 60 40)
All three colors have the same lightness and hue values. Increasing chroma makes the color more intense.
Another example changes the hue while retaining lightness and chroma:
lch(60% 40 40)
lch(60% 40 140)
lch(60% 40 240)
These colors occupy different directions around the LCH hue circle.
Because LCH is based on CIE Lab, its numeric lightness values are intended to correspond more closely to perceived lightness than conventional RGB values.
Lightness
The L component controls how light or dark a color appears.
It uses the same lightness scale as lab().
| Value | Meaning |
|---|---|
0% or 0 | Black |
25% or 25 | Dark |
50% or 50 | Medium lightness |
75% or 75 | Light |
100% or 100 | White |
For example:
.dark {
background-color: lch(25% 30 40);
}
.medium {
background-color: lch(50% 30 40);
}
.light {
background-color: lch(75% 30 40);
}
These colors share the same chroma and hue but use different lightness values.
Lightness values below 0 are clamped to 0, while values above 100 are clamped to 100.
At 0% lightness, the color displays as black. At 100%, it displays as white after gamut mapping.
Chroma
The C component controls chroma, which describes how far a color is from neutral gray.
Higher chroma generally produces a more colorful appearance.
For example:
lch(60% 0 40)
lch(60% 20 40)
lch(60% 40 40)
lch(60% 60 40)
All four colors have the same lightness and hue, but their chroma values increase.
At chroma 0, the result is neutral gray and the hue has no visible effect.
Unlike saturation in hsl(), chroma is not limited to a maximum of 100%.
For example:
color: lch(60% 150 40);
This is a valid color declaration, although the requested color may fall outside the display's supported gamut.
Negative chroma values are clamped to zero.
Chroma has no fixed upper bound in the syntax, but highly chromatic values may require gamut mapping.
Hue
The H component specifies a hue angle.
Hue can be written as a unitless number or an angle:
lch(60% 40 90)
lch(60% 40 90deg)
lch(60% 40 0.25turn)
lch(60% 40 100grad)
These examples specify equivalent hue angles.
The LCH hue circle differs from the HSL hue circle.
| Hue Angle | Approximate Color Direction |
|---|---|
0deg | Purplish red |
90deg | Yellow |
180deg | Greenish cyan |
270deg | Blue |
360deg | Same direction as 0deg |
For example:
color: lch(60% 40 0);
color: lch(60% 40 90);
color: lch(60% 40 180);
color: lch(60% 40 270);
Hue angles wrap around the color circle. A value of 360 degrees identifies the same direction as 0 degrees.
Do not assume a hue angle in lch() represents the same color as the identical angle in hsl() or oklch().
Transparency
The optional alpha component controls color opacity.
It follows a forward slash:
lch(L C H / alpha)
For example:
.box {
background-color: lch(60% 50 40 / 50%);
}
This creates a color with 50% opacity.
Alpha can use a number or percentage:
lch(60% 50 40 / 1)
lch(60% 50 40 / 0.75)
lch(60% 50 40 / 50%)
lch(60% 50 40 / 0)
The following pairs are equivalent:
0 = 0%
0.5 = 50%
1 = 100%
When alpha is omitted, an absolute LCH color is fully opaque.
Transparency controls how the color is composited with the background without changing its underlying LCH components.
Numbers and Percentages
The lightness and chroma components accept numbers or percentages, but their percentage scales differ.
| Component | Percentage Conversion |
|---|---|
L | 100% equals 100. |
C | 100% equals 150. |
H | Uses an angle or unitless number, not a percentage. |
alpha | 100% equals 1. |
For example, these colors are equivalent:
lch(60% 75 40)
lch(60 50% 40)
Both specify lightness 60, chroma 75, and hue 40 degrees.
Another equivalent pair:
lch(70% 30 120 / 0.5)
lch(70 20% 120deg / 50%)
Percentage conversions for chroma should not be confused with the percentage scale used for lightness or alpha.
Missing Components
The keyword none represents a missing color component.
For example:
lch(60% none 40)
lch(60% 40 none)
lch(none 0 0)
lch(60% 40 120 / none)
For ordinary rendering, a missing component generally behaves like zero.
However, missing components can retain special meaning during color interpolation and other color operations.
For example:
color: lch(60% none 40);
The missing chroma component behaves as zero when the color is rendered normally.
At zero chroma, the hue angle has no visible effect.
Do not assume none is always interchangeable with a numeric zero when colors are interpolated.
Relative Colors
Relative color syntax creates a new LCH color from an existing color.
The syntax begins with the from keyword:
lch(from color L C H / alpha)
For example:
.box {
background-color: lch(from red l c h);
}
The browser converts the origin color to LCH and uses its lightness, chroma, and hue components.
Individual components can be modified:
.lighter {
background-color: lch(from #336699 calc(l + 10) c h);
}
This increases the origin color's LCH lightness by 10 while retaining chroma and hue.
Another example reduces chroma:
.muted {
background-color: lch(from #336699 l calc(c * 0.6) h);
}
The available channel keywords are l, c, h, and alpha.
Relative color channel values are exposed as numbers, so calculations such as calc(l + 10) use a unitless value.
When alpha is omitted in relative color syntax, the output retains the origin color's alpha value.
Relative color syntax has a separate compatibility history from basic LCH colors.
Color Gamut
A color gamut is the range of colors that a color space or display can represent.
The CIE LCH color space can describe colors outside the standard sRGB gamut.
For example:
.box {
background-color: lch(65% 120 40);
}
This specifies a high-chroma color that may exceed the gamut of some displays.
When the requested color cannot be displayed directly, the browser maps it to a representable color.
This process is called gamut mapping.
As a result, two different LCH colors may appear similar if both are mapped into the same limited display gamut.
For predictable results, test important colors on standard and wide-gamut displays.
Using Gradients
LCH colors can be used as color stops in CSS gradients.
For example:
.gradient {
background: linear-gradient(
90deg,
lch(60% 50 40),
lch(60% 50 240)
);
}
The gradient transitions between two LCH colors.
The interpolation color space can also be specified:
.gradient {
background: linear-gradient(
in lch,
lch(60% 50 40),
lch(60% 50 240)
);
}
The in lch syntax requests interpolation in the LCH color space.
Hue interpolation can be controlled explicitly:
.gradient {
background: linear-gradient(
in lch longer hue,
lch(60% 50 40),
lch(60% 50 240)
);
}
The longer hue keyword selects the longer path around the hue circle.
Other hue interpolation methods include shorter hue, increasing hue, and decreasing hue.
Using LCH colors as gradient endpoints does not automatically require interpolation in LCH. Use the in lch syntax when that behavior is intended.
Using Custom Properties
CSS custom properties can store complete LCH colors or individual components.
For example:
:root {
--brand-color: lch(55% 50 250);
}
.button {
background-color: var(--brand-color);
}
The same color can be reused across multiple elements.
Individual components can also be stored:
:root {
--color-lightness: 60%;
--color-chroma: 45;
--color-hue: 240;
}
.card {
background-color: lch(var(--color-lightness) var(--color-chroma) var(--color-hue));
}
Changing a custom property updates the resulting color.
Transparency can be added:
.card {
background-color: lch(var(--color-lightness) var(--color-chroma) var(--color-hue) / 80%);
}
This approach is useful for building reusable color palettes and theme systems.
lch() vs. lab()
The lch() and lab() functions describe colors using related coordinate systems.
| Feature | lch() | lab() |
|---|---|---|
| Color model | CIE LCH | CIE Lab |
| Components | Lightness, chroma, hue | Lightness, a, b |
| Coordinates | Polar | Rectangular |
| Hue control | Explicit hue angle | Determined by a and b |
| Chroma control | Explicit chroma value | Determined by a and b |
| Transparency | Optional alpha | Optional alpha |
For example:
color: lab(60% 40 30);
color: lch(60% 50 36.87);
These values describe approximately the same color.
In LCH, chroma is calculated from the Lab color axes, while hue represents their direction.
Use lch() when directly adjusting hue and chroma is more convenient than working with the Lab axes.
lch() vs. hsl()
The lch() and hsl() functions both provide hue and lightness controls, but their underlying color models differ.
| Feature | lch() | hsl() |
|---|---|---|
| Color space | CIE LCH | sRGB-based HSL |
| Components | Lightness, chroma, hue | Hue, saturation, lightness |
| Lightness | Perceptual lightness | HSL lightness |
| Color intensity | Chroma | Saturation |
| Hue angles | CIE LCH hue circle | HSL hue circle |
| Color range | Can represent colors outside sRGB | Limited to sRGB |
For example:
color: hsl(0 100% 50%);
color: lch(54.29% 106.85 40.86);
These values describe approximately the same red color.
HSL hue angles do not correspond directly to LCH hue angles.
Use LCH when perceptual lightness and chroma control are important.
lch() vs. oklch()
The lch() and oklch() functions both use lightness, chroma, and hue, but they are based on different color models.
| Feature | lch() | oklch() |
|---|---|---|
| Color model | CIE LCH | OKLCH |
| Lightness scale | 0 to 100 | 0 to 1 |
| Chroma scale | 100% equals 150 | 100% equals 0.4 |
| Hue | CIE LCH hue angle | OKLCH hue angle |
| Perceptual behavior | Based on CIE Lab | Based on OKLab |
| Transparency | Optional alpha | Optional alpha |
For example:
color: lch(60% 50 40);
color: oklch(60% 0.15 40);
These values do not describe identical colors because the two color spaces use different component scales and hue mappings.
Do not substitute numeric values directly between lch() and oklch().
Example
This example demonstrates how changing the lightness component produces darker and lighter variations of a color.
HTML:
<div class="lch-lightness-demo">
<div class="lch-lightness-item">
<div class="lch-lightness-swatch lch-lightness-25"></div>
<span>25% Lightness</span>
</div>
<div class="lch-lightness-item">
<div class="lch-lightness-swatch lch-lightness-45"></div>
<span>45% Lightness</span>
</div>
<div class="lch-lightness-item">
<div class="lch-lightness-swatch lch-lightness-65"></div>
<span>65% Lightness</span>
</div>
<div class="lch-lightness-item">
<div class="lch-lightness-swatch lch-lightness-85"></div>
<span>85% Lightness</span>
</div>
</div>
CSS:
.lch-lightness-demo {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
gap: 10px;
max-width: 520px;
margin: 0 auto;
}
.lch-lightness-item {
min-width: 0;
text-align: center;
}
.lch-lightness-swatch {
height: 100px;
border: 1px solid #ccc;
}
.lch-lightness-item span {
display: block;
margin-top: 8px;
font-size: 12px;
}
.lch-lightness-25 { background-color: #453045; background-color: lch(25% 30 320); }
.lch-lightness-45 { background-color: #775b7a; background-color: lch(45% 30 320); }
.lch-lightness-65 { background-color: #ac8eaf; background-color: lch(65% 30 320); }
.lch-lightness-85 { background-color: #e1c5e2; background-color: lch(85% 30 320); }
All four colors use the same chroma and hue. Increasing lightness creates progressively lighter variations.
Chroma Example
This example shows how changing chroma affects color intensity while retaining the same lightness and hue.
HTML:
<div class="lch-chroma-demo">
<div class="lch-chroma-item">
<div class="lch-chroma-swatch lch-chroma-0"></div>
<span>Chroma 0</span>
</div>
<div class="lch-chroma-item">
<div class="lch-chroma-swatch lch-chroma-20"></div>
<span>Chroma 20</span>
</div>
<div class="lch-chroma-item">
<div class="lch-chroma-swatch lch-chroma-40"></div>
<span>Chroma 40</span>
</div>
<div class="lch-chroma-item">
<div class="lch-chroma-swatch lch-chroma-60"></div>
<span>Chroma 60</span>
</div>
</div>
CSS:
.lch-chroma-demo {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
gap: 10px;
max-width: 520px;
margin: 0 auto;
}
.lch-chroma-item {
min-width: 0;
text-align: center;
}
.lch-chroma-swatch {
height: 100px;
border: 1px solid #ccc;
}
.lch-chroma-item span {
display: block;
margin-top: 8px;
font-size: 12px;
}
.lch-chroma-0 { background-color: #919191; background-color: lch(60% 0 40); }
.lch-chroma-20 { background-color: #aa8784; background-color: lch(60% 20 40); }
.lch-chroma-40 { background-color: #c47d73; background-color: lch(60% 40 40); }
.lch-chroma-60 { background-color: #df705f; background-color: lch(60% 60 40); }
At chroma 0, the color is neutral gray. Increasing chroma produces progressively stronger color.
Hue Example
This example demonstrates how changing the hue angle produces different colors while retaining the same lightness and chroma.
HTML:
<div class="lch-hue-demo">
<div class="lch-hue-item">
<div class="lch-hue-swatch lch-hue-0"></div>
<span>0deg</span>
</div>
<div class="lch-hue-item">
<div class="lch-hue-swatch lch-hue-90"></div>
<span>90deg</span>
</div>
<div class="lch-hue-item">
<div class="lch-hue-swatch lch-hue-180"></div>
<span>180deg</span>
</div>
<div class="lch-hue-item">
<div class="lch-hue-swatch lch-hue-270"></div>
<span>270deg</span>
</div>
</div>
CSS:
.lch-hue-demo {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
gap: 10px;
max-width: 520px;
margin: 0 auto;
}
.lch-hue-item {
min-width: 0;
text-align: center;
}
.lch-hue-swatch {
height: 100px;
border: 1px solid #ccc;
}
.lch-hue-item span {
display: block;
margin-top: 8px;
font-size: 12px;
}
.lch-hue-0 { background-color: #bd7f92; background-color: lch(60% 40 0); }
.lch-hue-90 { background-color: #a39555; background-color: lch(60% 40 90); }
.lch-hue-180 { background-color: #54a19a; background-color: lch(60% 40 180); }
.lch-hue-270 { background-color: #8b8fbe; background-color: lch(60% 40 270); }
The four swatches use identical lightness and chroma values but different hue angles. Each angle selects a different direction around the LCH color circle.
Browser Fallbacks
Modern browsers support basic lch() colors, but older browsers may not recognize the function.
Provide a conventional color before the LCH declaration:
.button {
background-color: #c47d73;
background-color: lch(60% 40 40);
}
Browsers supporting lch() use the second declaration. Older browsers retain the first.
The fallback should approximate the intended LCH color.
For advanced features such as relative colors or explicit gradient interpolation, check browser support separately.
Common Uses
The lch() function is useful for color palettes, themes, and designs that require perceptual color adjustments.
| Use | Description |
|---|---|
| Color palettes | Create related colors by adjusting lightness, chroma, or hue. |
| Theme colors | Define consistent color families for interface components. |
| Lightness adjustments | Create darker and lighter color variations. |
| Chroma adjustments | Control color intensity independently from lightness. |
| Hue variations | Generate colors using hue angles. |
| Gradients | Interpolate colors in the LCH color space. |
| Wide-gamut design | Specify colors beyond the standard sRGB gamut. |
| Relative colors | Adjust LCH channels based on an existing color. |
For example:
.card {
background-color: lch(75% 30 250);
border-color: lch(45% 30 250);
}
Both colors share chroma and hue values but use different lightness levels.
Limitations
The lch() function has several important rules and limitations.
- Three color components are required in absolute syntax, although
nonecan represent a missing component. - Components must be separated by spaces, not commas.
- The optional alpha value follows a forward slash.
- Lightness values outside the 0 to 100 range are clamped.
- Negative chroma values are clamped to zero.
- Chroma is not restricted to a maximum of 100 or 100%.
- Hue angles do not correspond directly to HSL or OKLCH hue angles.
- At zero chroma, the hue has no visible effect.
- Colors outside the display gamut may be adjusted during rendering.
- Relative color syntax has separate compatibility considerations.
- Equal LCH lightness values do not guarantee accessible contrast.
For example, this is valid:
color: lch(60% 50 120 / 80%);
The following is invalid because commas are not allowed:
color: lch(60%, 50, 120);
The following is invalid because the required hue component is missing:
color: lch(60% 50);
Use the correct space-separated syntax and include all three color components.
Browser Support
The CSS lch() function is Baseline Widely available. Basic LCH colors have been supported across major browser engines since May 2023.
Modern versions of Chrome, Edge, Firefox, Safari, and other major browsers support LCH colors.
For example:
.box {
background-color: lch(60% 50 40);
}
Related features, including relative color syntax and explicit gradient interpolation, have separate browser compatibility histories.
For current compatibility information, visit Can I Use? and search for CSS lch() colors.
Specifications
The lch() function is defined in the CSS Color Module Level 4 .
Relative color syntax is further described in the CSS Color Module Level 5 .
Related CSS functions include lab(), oklch(), oklab(), hsl(), rgb(), and color-mix().
