CSS oklch() Function
The CSS oklch() function defines a color using perceptual lightness, chroma, and hue in the Oklch color space.
Oklch is the cylindrical representation of Oklab. It provides a more intuitive way to adjust a color's lightness, color intensity, and hue while maintaining more consistent perceived differences than traditional HSL calculations. It is useful for color palettes, design systems, gradients, and responsive color variations.
Syntax
oklch(L C H)
oklch(L C H / alpha)
The function uses three space-separated color components and an optional alpha value following a forward slash.
For example:
color: oklch(60% 0.15 250);
background-color: oklch(75% 0.12 140);
border-color: oklch(65% 0.18 30 / 0.5);
The first component controls lightness, the second controls chroma, and the third specifies hue.
The optional alpha component controls transparency.
Unlike legacy comma-separated color syntax, oklch() requires space-separated components.
The function returns a CSS <color> value and can be used with properties that accept colors.
Parameters
The oklch() function accepts three color components and an optional alpha component.
| Parameter | Description |
|---|---|
L |
Perceptual lightness. Typically expressed as a percentage, with 0% representing black and 100% representing reference white. |
C |
Chroma, representing the distance from neutral gray. Zero produces a neutral color, while larger positive values produce more colorful results. |
H |
Hue angle, expressed as a number in degrees or an angle value. |
alpha |
Optional opacity value. Zero is fully transparent and one is fully opaque. |
For example:
oklch(70% 0.15 240 / 0.8)
This defines a color with 70% lightness, chroma of 0.15, a hue angle of 240 degrees, and 80% opacity.
Lightness can also be written as a number, where 1 corresponds to 100%.
Chroma accepts numbers or percentages. For example, 25% chroma corresponds to 0.1, because 100% corresponds to 0.4.
Hue accepts unitless degrees or angle units such as deg, turn, and rad.
For example, these declarations describe the same color:
color: oklch(70% 0.1 90);
color: oklch(0.7 25% 90deg);
color: oklch(70% 0.1 0.25turn);
How It Works
Oklch describes color using three coordinates that correspond to lightness, color intensity, and hue direction.
- Lightness: Determines how light or dark the color appears.
- Chroma: Determines how far the color is from neutral gray.
- Hue: Determines the color's position around the Oklch hue circle.
For example:
oklch(60% 0 0)
Because chroma is zero, the result is a neutral gray. The hue does not affect its appearance.
Increasing chroma introduces color:
oklch(60% 0.05 250)
oklch(60% 0.1 250)
oklch(60% 0.15 250)
Changing the hue moves around the color circle:
oklch(70% 0.12 30)
oklch(70% 0.12 140)
oklch(70% 0.12 250)
Changing lightness makes the color lighter or darker while preserving the specified chroma and hue coordinates.
Oklch is based on an approximately perceptually uniform color space. Equal numerical changes are intended to produce more consistent visible changes, although perception and display limitations still affect the result.
Lightness
The first component controls perceptual lightness.
For example:
oklch(30% 0 0)
oklch(60% 0 0)
oklch(90% 0 0)
These values create progressively lighter neutral grays.
Another example keeps chroma and hue unchanged:
oklch(40% 0.1 250)
oklch(60% 0.1 250)
oklch(80% 0.1 250)
As lightness increases, the color becomes lighter while retaining its specified chroma and hue.
Lightness is especially useful when creating related colors for buttons, backgrounds, borders, and interface states.
However, not every combination of lightness and chroma can be displayed accurately. Some colors require gamut mapping.
Chroma
The second component controls chroma, which measures the distance from the neutral axis in the Oklab color space.
For example:
oklch(70% 0 250)
oklch(70% 0.05 250)
oklch(70% 0.1 250)
oklch(70% 0.15 250)
The first value is neutral gray because its chroma is zero.
As chroma increases, the color becomes more vivid along the selected hue direction.
Chroma is not identical to HSL saturation. The available chroma depends on lightness, hue, and the display's color gamut.
For example, a chroma value that is displayable at one hue may be outside the sRGB gamut at another hue.
Negative chroma values are clamped to zero, producing a neutral color.
Chroma is commonly written as a number, although percentages are also supported:
oklch(70% 0.1 250)
oklch(70% 25% 250)
Both expressions use the same chroma value.
Hue
The third component specifies the hue angle around the Oklch color circle.
For example:
oklch(70% 0.12 30)
oklch(70% 0.12 90)
oklch(70% 0.12 150)
oklch(70% 0.12 250)
Different angles produce different hue directions while preserving the specified lightness and chroma.
Approximate Oklch hue directions include:
| Hue Angle | Approximate Color Direction |
|---|---|
30 | Red-orange |
90 | Yellow |
150 | Green |
200 | Cyan |
260 | Blue |
320 | Pink-purple |
These are approximate directions rather than exact color names. The appearance also depends on lightness and chroma.
Hue angles wrap around a complete circle. For example:
oklch(70% 0.1 30)
oklch(70% 0.1 390)
These specify equivalent hue directions because 390 degrees is one full rotation plus 30 degrees.
When chroma is zero, hue has no visible effect because the color is neutral.
Alpha and Transparency
The optional alpha component controls opacity and follows a forward slash.
For example:
oklch(65% 0.15 250 / 1)
oklch(65% 0.15 250 / 0.5)
oklch(65% 0.15 250 / 0)
The first color is fully opaque, the second is 50% opaque, and the third is fully transparent.
Alpha can also be written as a percentage:
oklch(65% 0.15 250 / 50%)
This is equivalent to an alpha value of 0.5.
For example:
.overlay {
background-color: oklch(55% 0.12 250 / 0.4);
}
The overlay has 40% opacity, allowing the background behind it to remain partially visible.
Alpha changes transparency without changing the specified lightness, chroma, or hue coordinates.
Missing Components
Modern CSS color syntax allows the none keyword to represent a missing component.
For example:
oklch(70% none 250)
The chroma component is marked as missing.
Another example:
oklch(70% 0.12 none)
The hue component is marked as missing.
Missing components are particularly useful during color interpolation, where CSS may preserve missing component information or borrow values from another color.
Outside interpolation contexts, a missing component generally behaves like zero for rendering.
For example:
oklch(70% 0 none)
With zero chroma, the result is neutral regardless of hue.
The none keyword is not equivalent to omitting a required argument. All three main component positions must be present.
Relative Colors
Relative color syntax allows an Oklch color to be derived from an existing color.
For example:
.box {
color: oklch(from #0066cc l c h);
}
The source color is converted into Oklch, and its lightness, chroma, and hue components are reused.
Individual components can be modified:
.box {
color: oklch(from #0066cc calc(l + 0.1) c h);
}
This increases the lightness component by 0.1, equivalent to 10 percentage points.
Another example reduces chroma:
.box {
color: oklch(from #0066cc l calc(c * 0.5) h);
}
This reduces the original chroma by half.
Hue can also be adjusted:
.box {
color: oklch(from #0066cc l c calc(h + 30));
}
This rotates the hue by 30 degrees in the Oklch color space.
Relative colors can use CSS custom properties:
:root {
--brand-color: #0066cc;
}
.button {
background-color: var(--brand-color);
}
.button:hover {
background-color: oklch(from var(--brand-color) calc(l + 0.1) c h);
}
.button:active {
background-color: oklch(from var(--brand-color) calc(l - 0.1) c h);
}
Relative color syntax has separate browser compatibility requirements from basic oklch() notation.
Out-of-Gamut Colors
Oklch can describe colors outside the range that a particular display or color space can reproduce.
For example:
oklch(70% 0.4 250)
This specifies a high chroma value that may be outside the sRGB gamut.
When a color cannot be reproduced directly, the browser uses gamut mapping to produce a displayable result.
Gamut mapping can change the displayed chroma and other color characteristics.
The maximum displayable chroma is not constant across all lightness and hue values.
For example, a chroma of 0.2 may be displayable for one combination of lightness and hue but not another.
When designing color palettes, test the resulting colors on common displays and verify that important color differences remain visible.
Wide-gamut displays can reproduce more colors than standard sRGB displays, but they still have limits.
oklch() vs. oklab()
The oklch() and oklab() functions represent the same underlying color space using different coordinate systems.
| Feature | oklch() | oklab() |
|---|---|---|
| Coordinate system | Cylindrical | Rectangular |
| First component | Lightness | Lightness |
| Second component | Chroma | a-axis |
| Third component | Hue angle | b-axis |
| Typical use | Color palettes and hue adjustments | Color-axis calculations and interpolation |
For example:
oklch(60% 0.1414 45)
oklab(60% 0.1 0.1)
These represent approximately the same color.
The conversion between the two coordinate systems uses:
a = C * cos(H)
b = C * sin(H)
The hue angle is interpreted using the appropriate angular units.
Oklch is often more convenient for designers because lightness, chroma, and hue can be adjusted independently.
oklch() vs. hsl()
The oklch() and hsl() functions both describe colors using three components, but their underlying color models differ.
| Feature | oklch() | hsl() |
|---|---|---|
| Color model | Perceptual Oklab-based model | HSL derived from sRGB |
| Components | Lightness, chroma, hue | Hue, saturation, lightness |
| Lightness behavior | Approximately perceptually uniform | Not perceptually uniform |
| Color range | Can represent wide-gamut colors | Limited to sRGB |
| Typical use | Perceptual color adjustments | Traditional web color selection |
For example:
color: oklch(65% 0.15 250);
color: hsl(250 70% 60%);
These do not describe equivalent colors because their coordinate systems differ.
In HSL, equal changes in lightness do not necessarily produce equal perceived changes across different hues.
Oklch provides a more consistent basis for creating color variations, although its perceptual uniformity is approximate.
Example
This example demonstrates different hue values while keeping lightness and chroma constant.
HTML:
<div class="oklch-demo">
<div class="oklch-demo-item oklch-demo-orange">30deg</div>
<div class="oklch-demo-item oklch-demo-yellow">90deg</div>
<div class="oklch-demo-item oklch-demo-green">150deg</div>
<div class="oklch-demo-item oklch-demo-blue">250deg</div>
</div>
CSS:
.oklch-demo {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 12px;
}
.oklch-demo-item {
display: flex;
align-items: center;
justify-content: center;
min-height: 90px;
padding: 10px;
color: #111111;
text-align: center;
font-size: 14px;
}
.oklch-demo-orange {
background-color: oklch(75% 0.12 30);
}
.oklch-demo-yellow {
background-color: oklch(75% 0.12 90);
}
.oklch-demo-green {
background-color: oklch(75% 0.12 150);
}
.oklch-demo-blue {
background-color: oklch(75% 0.12 250);
}
All four colors use 75% lightness and a chroma value of 0.12.
Only the hue angle changes, producing different color directions around the Oklch color circle.
Lightness Example
This example creates three related colors by changing only the lightness component.
HTML:
<div class="oklch-lightness-demo">
<div class="oklch-lightness-item oklch-lightness-dark">40% Lightness</div>
<div class="oklch-lightness-item oklch-lightness-medium">60% Lightness</div>
<div class="oklch-lightness-item oklch-lightness-light">80% Lightness</div>
</div>
CSS:
.oklch-lightness-demo {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 10px;
}
.oklch-lightness-item {
display: flex;
align-items: center;
justify-content: center;
min-height: 100px;
padding: 10px;
text-align: center;
font-size: 12px;
}
.oklch-lightness-dark {
background-color: oklch(40% 0.1 250);
color: #ffffff;
}
.oklch-lightness-medium {
background-color: oklch(60% 0.1 250);
color: #ffffff;
}
.oklch-lightness-light {
background-color: oklch(80% 0.1 250);
color: #111111;
}
The chroma and hue values remain unchanged, while lightness increases from 40% to 80%.
This technique is useful for creating lighter and darker variations of a design color.
Chroma Example
This example demonstrates how increasing chroma changes a color's intensity while keeping lightness and hue constant.
HTML:
<div class="oklch-chroma-demo">
<div class="oklch-chroma-item oklch-chroma-zero">0 Chroma</div>
<div class="oklch-chroma-item oklch-chroma-low">0.05 Chroma</div>
<div class="oklch-chroma-item oklch-chroma-medium">0.10 Chroma</div>
<div class="oklch-chroma-item oklch-chroma-high">0.15 Chroma</div>
</div>
CSS:
.oklch-chroma-demo {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 12px;
}
.oklch-chroma-item {
display: flex;
align-items: center;
justify-content: center;
min-height: 90px;
padding: 10px;
color: #111111;
text-align: center;
font-size: 13px;
}
.oklch-chroma-zero {
background-color: oklch(75% 0 250);
}
.oklch-chroma-low {
background-color: oklch(75% 0.05 250);
}
.oklch-chroma-medium {
background-color: oklch(75% 0.1 250);
}
.oklch-chroma-high {
background-color: oklch(75% 0.15 250);
}
The first box is neutral gray because its chroma is zero.
Each subsequent box uses a larger chroma value, producing a more colorful result along the same hue direction.
Common Uses
The oklch() function is useful when creating colors that need systematic adjustments to lightness, chroma, or hue.
| Use | Description |
|---|---|
| Color palettes | Create related colors using consistent lightness and chroma adjustments. |
| Design systems | Define reusable color scales and interface states. |
| Hover and active states | Adjust lightness while preserving chroma and hue. |
| Color harmonies | Create related colors by changing hue angles. |
| Gradients | Interpolate colors in a perceptually oriented color space. |
| Relative colors | Generate variations from an existing CSS color. |
| Transparency | Specify opacity within the color function. |
| Wide-gamut colors | Represent colors beyond standard sRGB. |
For example:
.button {
background-color: oklch(60% 0.12 250);
}
.button:hover {
background-color: oklch(70% 0.12 250);
}
.button:active {
background-color: oklch(50% 0.12 250);
}
These button states preserve chroma and hue while changing lightness.
Oklch can also be used with color-mix():
.panel {
background-color: color-mix(
in oklch,
oklch(70% 0.15 250) 50%,
white
);
}
This mixes the specified Oklch color with white using Oklch interpolation.
For gradients, Oklch interpolation can be requested explicitly:
.gradient {
background: linear-gradient(
in oklch,
oklch(70% 0.15 30),
oklch(70% 0.15 250)
);
}
When interpolating hues, CSS follows the selected hue interpolation method, which can affect the intermediate colors.
Limitations
The oklch() function has several important rules and limitations.
- Three main component positions are required.
- Components use space-separated syntax, not commas.
- The optional alpha component follows a forward slash.
- Chroma is not equivalent to HSL saturation.
- The maximum displayable chroma varies with lightness and hue.
- Some valid Oklch colors fall outside a display's color gamut.
- Out-of-gamut colors may be mapped to different displayable colors.
- Perceptual uniformity is approximate rather than exact.
- Relative color syntax has separate browser compatibility requirements.
- Older browsers may not recognize Oklch color notation.
- Text and background contrast must still be checked for accessibility.
For example, this is valid:
color: oklch(70% 0.15 250);
The following is invalid because it uses commas:
color: oklch(70%, 0.15, 250);
The following is invalid because the hue component is missing:
color: oklch(70% 0.15);
To mark the hue as missing, use none:
color: oklch(70% 0.15 none);
When older browser compatibility is required, provide a fallback color before the Oklch declaration.
Browser Support
The CSS oklch() function is Baseline Widely available. Support across major browser engines began in 2023.
Modern versions of Chrome, Edge, Firefox, Safari, and other major browsers support Oklch color notation.
For example:
.box {
background-color: oklch(65% 0.15 250);
}
For older browsers, provide a fallback declaration:
.box {
background-color: #4477cc;
background-color: oklch(65% 0.15 250);
}
Browsers supporting oklch() use the Oklch color, while unsupported browsers retain the hexadecimal fallback.
The fallback is an approximate alternative and is not necessarily an exact conversion.
Relative color syntax, including oklch(from ...), has separate compatibility considerations.
For current compatibility information, visit Can I Use? and search for Oklab color model.
Specifications
The oklch() function is defined in the CSS Color Module Level 4 .
Relative color syntax is defined in the CSS Color Module Level 5 .
Related CSS functions include oklab(), lab(), lch(), hsl(), color(), and color-mix().
