Color converter
HEX to OKLCH and OKLCH to HEX
Type a hex code to get its OKLCH and OKLab values, or an oklch() color to get the nearest hex. A color outside sRGB is brought inside by lowering its chroma, keeping lightness and hue, and the page says how much was lost.
The converter needs JavaScript. The result shown is for #D3AF37, and the worked examples below read without it.
Result
Inside sRGB
Showing the last color that converted.
- OKLCH
oklch(76.55% 0.13847 91.55)- HEX
#D3AF37- OKLab
oklab(76.55% -0.00375 0.13842)
- Back to hex
- #D3AF37 unchangedchanged
- Chroma kept
- Chroma lost
- Rounding error
- ΔE2000 0.003
- Hex against the color as written
OKLCH to HEX
Adjust it in OKLCH
Move lightness, chroma and hue; the hex, the gamut and the CSS follow. The chroma track is hatched where sRGB ends, and its tick marks where Display P3 ends.
The sliders need JavaScript.
- sRGB Inside
- Display P3 Inside
- Rec. 2020 Inside
Outside sRGB: the hex keeps the lightness and hue and lowers the chroma until the color fits.
No hue: with chroma at 0, the color is a gray and its hue is written as none.
- OKLCH
oklch(76.55% 0.13847 91.55)- HEX
#D3AF37- Chroma kept
- 0.13847
- Chroma lost
- 0.0%
- Hex against the color as written
- ΔE2000 0.003
CSS with a fallback
color: #d3af37;
color: oklch(76.55% 0.13847 91.55);
Browsers that do not read oklch() skip the second line and keep the hex.
Only on wide-gamut screens
Every screen gets the hex; screens that report a Display P3 gamut get the full color instead.
Why OKLCH
Lightness you can trust
OKLCH is lightness, chroma and hue in OKLab, a color space Björn Ottosson designed in 2020 so that equal steps look equal.
Read the Oklab and Oklch guideChange the hue and the lightness you see stays where it was, which HSL cannot promise. hsl(60 100% 50%) and hsl(240 100% 50%) both claim 50% lightness, yet in OKLCH the yellow sits at 96.8% and the blue at 45.2%.
So you can build a scale by stepping L, rotate a hue and keep its weight, or check that two colors are equally light by reading one number. Every color page lists its OKLCH values, shades and gamut.
Method
Rounding, gamuts and gray
OKLCH comes out as oklch(L% C h): lightness to two decimal places of a percent, chroma to five decimal places, hue to two, with trailing zeros dropped.
Why five places of chroma
At this rounding, every one of the 16,777,216 six-digit hex colors comes back unchanged, and a test checks all of them. With chroma rounded to four places, as many tools do, some come back one step off in a channel: #00C0F3 returns as #01C0F3. The rounding error for your color is shown as a CIEDE2000 difference; below 1 is too small to see.
Gray has no hue
When the chroma rounds to 0, the hue is written as none. CSS Color 4 does the same when it converts a gray, because a tiny leftover chroma gives a hue angle that is noise. none draws the same color as 0, but a gradient or color-mix() then takes the hue from the other color instead of swinging through red.
Inside a gamut, to half a step
A color counts as inside sRGB, or inside Display P3, when every channel is within half an 8-bit step of the range: the hex is then the same whether a browser clips the color or maps it. Without that tolerance, a pasted oklch(62.8% 0.2577 29.23), which is sRGB's red rounded, would be reported as outside sRGB. Rec. 2020 is tested on its linear values.
Colors outside sRGB
OKLCH can describe colors no sRGB screen can show. The hex here keeps the lightness and hue and lowers the chroma until the color fits, which is the idea behind CSS Color 4's gamut mapping. That specification lets browsers choose among three mapping algorithms, so writing the hex yourself as the fallback fixes what screens without wide gamut show.
How gamut mapping worksExamples
Worked examples
Each row is the converter's own output, and a test re-runs every row. The sRGB primaries match the values the CSS Color 4 sample code gives.
HEX to OKLCH
| HEX | OKLCH | OKLab | Back to hex | Rounding error |
|---|---|---|---|---|
#FFFFFF | oklch(100% 0 none) | oklab(100% 0 0) | #FFFFFF | 0.000 |
#000000 | oklch(0% 0 none) | oklab(0% 0 0) | #000000 | 0.000 |
#808080 | oklch(59.99% 0 none) | oklab(59.99% 0 0) | #808080 | 0.003 |
#FF0000 | oklch(62.8% 0.25768 29.23) | oklab(62.8% 0.22486 0.12585) | #FF0000 | 0.010 |
#00FF00 | oklch(86.64% 0.29483 142.5) | oklab(86.64% -0.23389 0.1795) | #00FF00 | 0.005 |
#0000FF | oklch(45.2% 0.31321 264.05) | oklab(45.2% -0.03246 -0.31153) | #0000FF | 0.001 |
#FFFF00 | oklch(96.8% 0.21101 109.77) | oklab(96.8% -0.07137 0.19857) | #FFFF00 | 0.001 |
#D3AF37 | oklch(76.55% 0.13847 91.55) | oklab(76.55% -0.00375 0.13842) | #D3AF37 | 0.003 |
OKLCH to HEX
| OKLCH | Smallest gamut that holds it | HEX | Chroma kept | Chroma lost | ΔE2000 | Why |
|---|---|---|---|---|---|---|
oklch(70% 0.1 200) | sRGB | #40B1B7 | 0.1 | 0.0% | 0.068 | A calm teal, well inside sRGB |
oklch(62.8% 0.2577 29.23) | sRGB | #FF0000 | 0.2577 | 0.0% | 0.008 | sRGB's red, rounded: within half a step, so still sRGB |
oklch(64.85% 0.29947 28.96) | Display P3 | #FF3428 | 0.23751 | 20.7% | 9.87 | Display P3's red primary |
oklch(70% 0.25 145) | Display P3 | #00BF34 | 0.22016 | 11.9% | 2.74 | A green that P3 screens can show |
oklch(82.98% 0.46831 152.59) | Rec. 2020 | #00ED7E | 0.21548 | 54.0% | 17.03 | Rec. 2020's green primary |
oklch(60% 0.4 30) | Beyond Rec. 2020 | #EE1300 | 0.24068 | 39.8% | 18.29 | More chroma than any of the three holds |
oklch(50% 0 none) | sRGB | #636363 | 0 | 0.0% | 0.032 | No chroma, so no hue |
The rounding error is the CIEDE2000 difference between the hex and its rounded OKLCH value; the ΔE2000 column is the difference between the color as written and its hex, which for a color outside sRGB is mostly the chroma given up.
Next
Where to go from here
- HEX and RGBHex codes, rgb() and rgba() with alpha, and a batch list to CSS or CSV.
- Color Space ConverterThe same color in 34 notations, with its gamut headroom.
- Color pages635 colors, each with an OKLCH studio, shades and design tokens.
- Oklab and OklchWhy equal steps finally look equal, and when to reach for oklch() over HSL.
- Gamut mappingClipping, compression and why naive clipping shifts hue.
Method
Sources and testing
- CSS Color Module Level 4, 9.4: the oklab() and oklch() functions w3.org
- CSS Color Module Level 4, 14.2: CSS gamut mapping to an RGB destination w3.org
- CSS Color Module Level 4: sample code for color conversions w3.org
- Media Queries Level 4: the color-gamut feature w3.org
- Björn Ottosson, A perceptual color space for image processing (2020) bottosson.github.io
- Conversions run in your browser with the site's shared color code; nothing you type is sent anywhere.
- An automated test recomputes every example on this page, and the converter itself is unit-tested against the CSS Color 4 examples.
- Checked with a keyboard, the axe engine and Playwright in Chromium, in light and dark themes at phone and desktop widths. It has not yet been checked with a screen reader.
Found a mistake? Tell us and we will correct it.