oklch()
Baseline Widely available *
This feature is well established and works across many devices and browser versions. It’s been available across browsers since May 2023.
* Some parts of this feature may have varying levels of support.
Theoklch() functional notation expresses a given color in the Oklabcolor space.oklch() is the cylindrical form ofoklab(), using the sameL axis, but with polar Chroma (C) and Hue (h) coordinates.
In this article
Syntax
/* Absolute values */oklch(40.1% 0.123 21.57)oklch(59.69% 0.156 49.77)oklch(59.69% 0.156 49.77 / .5)/* Relative values */oklch(from green l c h / 0.5)oklch(from #123456 calc(l + 0.1) c h)oklch(from hsl(180 100% 50%) calc(l - 0.1) c h)oklch(from var(--color) l c h / calc(alpha - 0.1))Values
Below are descriptions of the allowed values for both absolute andrelative colors.
Note:Usually when percentage values have a numeric equivalent in CSS,100% is equal to the number1.This is not the case for all of theoklch() component values. Here,100% is equal to0.4 for theC value.
Absolute value syntax
oklch(L C H[ / A])
The parameters are as follows:
LA
<number>between0and1, a<percentage>between0%and100%, or the keywordnone(equivalent to0%in this case). In this case, the number0corresponds to0%(black) and the number1corresponds to100%(white). This value specifies the color's perceived lightness, or "brightness".Note:The
Linoklch()is the perceived lightness, which refers to the "brightness" we visually perceive with our eyes. This is different from theLinhsl(), where it represents lightness as compared to other colors.CA
<number>, a<percentage>, or the keywordnone(equivalent to0%in this case). This value is a measure of the color's chroma (roughly representing the "amount of color"). Its minimum useful value is0, while the maximum is theoretically unbounded (but in practice does not exceed0.5). In this case,0%is0and100%is the number0.4.HA
<number>, an<angle>, or the keywordnone(equivalent to0degin this case) representing the color's<hue>angle.Note:The angles corresponding to particular hues differ across the sRGB (used by
hsl()andhwb()), CIELAB (used bylch()), and Oklab (used byoklch()) color spaces. See theHues inoklch()example below and the<hue>reference page for more details and examples.AOptionalAn
<alpha-value>representing the alpha channel value of the color, where the number0corresponds to0%(fully transparent) and1corresponds to100%(fully opaque). Additionally, the keywordnonecan be used to explicitly specify no alpha channel. If theAchannel value is not explicitly specified, it defaults to 100%. If included, the value is preceded by a slash (/).
Note:SeeMissing color components for more information on the effect ofnone.
Relative value syntax
oklch(from <color> L C H[ / A])
The parameters are as follows:
from <color>The keyword
fromis always included when defining a relative color, followed by a<color>value representing theorigin color: This is the original color that the relative color is based on. The origin color can beany valid<color>syntax, including another relative color.LA
<number>between0and1, a<percentage>between0%and100%, or the keywordnone(equivalent to0%in this case). This represents the lightness value of the output color. Here the number0corresponds to0%(black) and the number1corresponds to100%(white).CA
<number>, a<percentage>, or the keywordnone(equivalent to0%in this case). This value represents the output color's chroma value (roughly representing the "amount of color"). Its minimum useful value is0, while its maximum is theoretically unbounded (but in practice does not exceed0.5). In this case,0%is0and100%is the number0.4.HA
<number>, an<angle>, or the keywordnone(equivalent to0degin this case) representing the output color's<hue>angle. See asample of different hues in theExamples section below.AOptionalAn
<alpha-value>representing the alpha channel value of the output color, where the number0corresponds to0%(fully transparent) and1corresponds to100%(fully opaque). Additionally, the keywordnonecan be used to explicitly specify no alpha channel. If theAchannel value is not explicitly specified, it defaults to the alpha channel value of the origin color. If included, the value is preceded by a slash (/).
Defining relative color output channel components
When using relative color syntax inside anoklch() function, the browser converts the origin color into an equivalent OkLCh color (if it is not already specified as such). The color is defined as three distinct color channel values —l (lightness),c (chroma), andh (hue) — plus an alpha channel value (alpha). These channel values are made available inside the function to be used when defining the output color channel values:
- The
lchannel value is resolved to a<number>between0and1, inclusive. - The
cchannel value is resolved to a<number>between0and0.4, inclusive. - The
hchannel value is resolved to a<number>between0and360, inclusive. - The
alphachannel is resolved to a<number>between0and1, inclusive.
When defining a relative color, the different channels of the output color can be expressed in several different ways. Below, we'll study some examples to illustrate these.
In the first two examples below, we are using relative color syntax. However, the first one outputs the same color as the origin color and the second one outputs a color not based on the origin color at all. They don't really create relative colors! You'd be unlikely to ever use these in a real codebase, and would probably just use an absolute color value instead. We included these examples as a starting point for learning about relativeoklch() syntax.
Let's start with an origin color ofhsl(0 100% 50%) (equivalent tored). The following function outputs the same color as the origin color — it uses the origin color'sl,c, andh channel values (0.627966,0.257704, and29.2346) as the output channel values:
oklch(from hsl(0 100% 50%) l c h)This function's output color isoklch(0.627966 0.257704 29.2346).
The next function uses absolute values for the output color's channel values, outputting a completely different color not based on the origin color:
oklch(from hsl(0 100% 50%) 42.1% 0.25 328.363)In the above case, the output color isoklch(0.421 0.25 328.363).
The following function creates a relative color based on the origin color:
oklch(from hsl(0 100% 50%) 0.8 0.4 h)This example:
- Converts the
hsl()origin color to an equivalentoklch()color —oklch(0.627966 0.257704 29.2346). - Sets the
Hchannel value for the output color to that of the originoklch()equivalent'sHchannel value —29.2346. - Sets the output color's
LandCchannel values to new values not based on the origin color:0.8and0.4respectively.
The final output color isoklch(0.8 0.4 29.2346).
Note:As mentioned above, if the output color is using a different color model to the origin color, the origin color is converted to the same model as the output color in the background so that it can be represented in a way that is compatible (i.e., using the same channels).
In the examples we've seen so far in this section, the alpha channels have not been explicitly specified for either the origin or output colors. When the output color alpha channel is not specified, it defaults to the same value as the origin color alpha channel. When the origin color alpha channel is not specified (and it is not a relative color), it defaults to1. Therefore, the origin and output alpha channel values are1 for the above examples.
Let's look at some examples that specify origin and output alpha channel values. The first one specifies the output alpha channel value as being the same as the origin alpha channel value, whereas the second one specifies a different output alpha channel value, unrelated to the origin alpha channel value.
oklch(from hsl(0 100% 50% / 0.8) l c h / alpha)/* Computed output color: oklch(0.627966 0.257704 29.2346 / 0.8) */oklch(from hsl(0 100% 50% / 0.8) l c h / 0.5)/* Computed output color: oklch(0.627966 0.257704 29.2346 / 0.5) */In the following example, thehsl() origin color is again converted to theoklch() equivalent —oklch(0.627966 0.257704 29.2346).calc() calculations are applied to theL,C,H, andA values, resulting in an output color ofoklch(0.827966 0.357704 9.23462 / 0.9):
oklch(from hsl(0 100% 50%) calc(l + 0.2) calc(c + 0.1) calc(h - 20) / calc(alpha - 0.1))Note:Because the origin color channel values are resolved to<number> values, you have to add numbers to them when using them in calculations, even in cases where a channel would normally accept<percentage>,<angle>, or other value types. Adding a<percentage> to a<number>, for example, doesn't work.
Formal syntax
<oklch()> =
oklch([from<color>]?[<percentage>|<number>|none][<percentage>|<number>|none][<hue>|none][ /[<alpha-value>|none]]?)
<hue> =
<number>|
<angle>
<alpha-value> =
<number>|
<percentage>
Examples
>Adjusting the brightness of a color
This example shows the effect of varying theL (lightness) value of theoklch() functional notation.
HTML
<div data-color="blue-dark"></div><div data-color="blue"></div><div data-color="blue-light"></div><div data-color="red-dark"></div><div data-color="red"></div><div data-color="red-light"></div><div data-color="green-dark"></div><div data-color="green"></div><div data-color="green-light"></div>CSS
body { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 20px;}div { height: 50px; border: 1px solid black;}[data-color="blue-dark"] { background-color: oklch(10% 0.4 240);}[data-color="blue"] { background-color: oklch(50% 0.4 240);}[data-color="blue-light"] { background-color: oklch(90% 0.4 240);}[data-color="red-dark"] { background-color: oklch(10% 0.4 20);}[data-color="red"] { background-color: oklch(50% 0.4 20);}[data-color="red-light"] { background-color: oklch(90% 0.4 20);}[data-color="green-dark"] { background-color: oklch(10% 0.4 130);}[data-color="green"] { background-color: oklch(50% 0.4 130);}[data-color="green-light"] { background-color: oklch(90% 0.4 130);}Result
Adjusting color intensity via chroma
The following example shows the effect of varying theC (chroma) value of theoklch() functional notation, with colors decreasing in intensity as theC value decreases from fully saturated to almost grey.
HTML
<div data-color="blue"></div><div data-color="blue-chroma1"></div><div data-color="blue-chroma2"></div><div data-color="blue-chroma3"></div><div data-color="red"></div><div data-color="red-chroma1"></div><div data-color="red-chroma2"></div><div data-color="red-chroma3"></div><div data-color="green"></div><div data-color="green-chroma1"></div><div data-color="green-chroma2"></div><div data-color="green-chroma3"></div>CSS
With the initial starting colors blue, red, and green, we declare progressively smaller values for chroma on them: starting from full color saturation at the high value of0.4 (equivalent to100%) down to0.01 (equivalent to2%), which is almost grey for all the colors.
body { display: grid; grid-template-columns: 1fr 1fr 1fr 1fr; gap: 20px;}div { height: 50px; border: 1px solid black;}[data-color="blue"] { background-color: oklch(50% 0.4 240);}[data-color="blue-chroma1"] { background-color: oklch(50% 0.2 240);}[data-color="blue-chroma2"] { background-color: oklch(50% 0.1 240);}[data-color="blue-chroma3"] { background-color: oklch(50% 0.01 240);}[data-color="red"] { background-color: oklch(50% 100% 20deg);}[data-color="red-chroma1"] { background-color: oklch(50% 50% 20deg);}[data-color="red-chroma2"] { background-color: oklch(50% 25% 20deg);}[data-color="red-chroma3"] { background-color: oklch(50% 2% 20deg);}[data-color="green"] { background-color: oklch(50% 0.4 130);}[data-color="green-chroma1"] { background-color: oklch(50% 0.2 130);}[data-color="green-chroma2"] { background-color: oklch(50% 0.1 130);}[data-color="green-chroma3"] { background-color: oklch(50% 0.01 130);}Result
If we had used0 instead of0.01 and2%, with the same lightness values, the colors would have all been the same shade of grey. In this example, they are almost grey.
Hues in OkLCh
The following example shows swatches with differentH (hue) values of theoklch() functional notation.
HTML
<div data-color="0">0deg</div><div data-color="20">20deg</div><div data-color="40">40deg</div><div data-color="60">60deg</div>and so on.
<div data-color="80">80deg</div><div data-color="100">100deg</div><div data-color="120">120deg</div><div data-color="140">140deg</div><div data-color="160">160deg</div><div data-color="180">180deg</div><div data-color="200">200deg</div><div data-color="220">220deg</div><div data-color="240">240deg</div><div data-color="260">260deg</div><div data-color="280">280deg</div><div data-color="300">300deg</div><div data-color="320">320deg</div><div data-color="340">340deg</div><div data-color="360">360deg</div>CSS
body { display: flex; flex-wrap: wrap; gap: 3px;}div { flex: 0 0 4em; text-align: center; line-height: 4em; display: inline-block; border: 1px solid black; color: white; font-family: monospace;}[data-color="0"] { background-color: oklch(50% 0.4 0deg);}[data-color="20"] { background-color: oklch(50% 0.4 20deg);}[data-color="40"] { background-color: oklch(50% 0.4 40deg);}[data-color="60"] { background-color: oklch(50% 0.4 60deg);}and so on.
[data-color="80"] { background-color: oklch(50% 0.4 80deg);}[data-color="100"] { background-color: oklch(50% 0.4 100deg);}[data-color="120"] { background-color: oklch(50% 0.4 120deg);}[data-color="140"] { background-color: oklch(50% 0.4 140deg);}[data-color="160"] { background-color: oklch(50% 0.4 160deg);}[data-color="180"] { background-color: oklch(50% 0.4 180deg);}[data-color="200"] { background-color: oklch(50% 0.4 200deg);}[data-color="220"] { background-color: oklch(50% 0.4 220deg);}[data-color="240"] { background-color: oklch(50% 0.4 240deg);}[data-color="260"] { background-color: oklch(50% 0.4 260deg);}[data-color="280"] { background-color: oklch(50% 0.4 280deg);}[data-color="300"] { background-color: oklch(50% 0.4 300deg);}[data-color="320"] { background-color: oklch(50% 0.4 320deg);}[data-color="340"] { background-color: oklch(50% 0.4 340deg);}[data-color="360"] { background-color: oklch(50% 0.4 360deg);}Result
The hue angles inoklch() are different from those inhsl(). See<hue> for more information. Inhsl(), the sRGB color0deg represents red. However, in the CIELab color space,0deg corresponds to magenta, while red is approximately41deg.
Adjusting the alpha value of a color
The following example shows the effect of varying theA (alpha) value of theoklch() color function.Thered andred-alpha elements overlap the#background-div element to demonstrate the effect of opacity.GivingA a value of0.4 makes the color 40% opaque.
HTML
<div> <div data-color="red"></div> <div data-color="red-alpha"></div></div>CSS
div { width: 50px; height: 50px; padding: 5px; margin: 5px; display: inline-block; border: 1px solid black;}#background-div { background-color: oklch(100% 0.57 217); width: 150px; height: 40px;}[data-color="red"] { background-color: oklch(50% 0.5 20);}[data-color="red-alpha"] { background-color: oklch(50% 0.5 20 / 0.4);}Result
Using relative colors with oklch()
This example styles three<div> elements with different background colors. The middle one is given the unmodified--base-color, while the left and right ones are given lightened and darkened variants of that--base-color.
These variants are defined using relative colors — the--base-colorcustom property is passed into anoklch() function, and the output colors have their lightness channel modified to achieve the desired effect via acalc() function. The lightened color has0.15 (15%) added to the lightness channel, and the darkened color has0.15 (15%) subtracted from the lightness channel.
<div> <div></div> <div></div> <div></div></div>CSS
#container { display: flex; width: 100vw; height: 100vh; box-sizing: border-box;}.item { flex: 1; margin: 20px;}:root { --base-color: orange;}#one { background-color: oklch(from var(--base-color) calc(l + 0.15) c h);}#two { background-color: var(--base-color);}#three { background-color: oklch(from var(--base-color) calc(l - 0.15) c h);}Result
The output is as follows:
Specifications
| Specification |
|---|
| CSS Color Module Level 5> # relative-Oklch> |
| CSS Color Module Level 4> # ok-lab> |
Browser compatibility
See also
- List of all color notations
- Using relative colors
- CSS colors module
<hue>data typelch()andoklab()color functions- Interactive post on OkLCh color space (2024)
- OKLCH in CSS: why we moved from RGB and HSL (2024)
- A perceptual color space for image processing (2020)