Skip to content
oklchhexcolor conversionCSScolor modelsfrontend

OKLCH to HEX: How to Convert Modern CSS Colors (and Why You Sometimes Should Not)

HB
Hue Blender
·6 min read

oklch() is the most powerful color function in modern CSS, but a lot of the toolchain still speaks hex. Design tokens get exported to JSON for native apps. Marketing decks want a color picker that returns #3A86FF. The brand book hands you twelve hex values and asks for a perceptually uniform tonal scale on top of them. Converting between OKLCH and hex is the bridge that lets you adopt OKLCH in CSS without breaking everything else.

This guide walks through the practical conversion — what changes, what gets lost, and when each format earns its place.

The Short Version

  • OKLCH → hex is straightforward when the OKLCH color is inside the sRGB gamut. It always loses one thing: chroma above the sRGB ceiling gets clamped or remapped.
  • Hex → OKLCH is mathematically lossless. Every sRGB hex maps to exactly one OKLCH triplet.
  • Round-tripping (OKLCH → hex → OKLCH) is lossless only for OKLCH colors already inside sRGB. Once you step outside, the round trip changes the chroma.

You can do both conversions interactively at Hue Blender's color converter or with the OKLCH picker, which shows the equivalent hex live as you adjust L, C, and H.

How the Conversion Actually Works

OKLCH is the cylindrical form of Oklab (Björn Ottosson, 2020). Converting OKLCH to hex is a four-step pipeline:

  1. OKLCH → Oklab. Convert chroma and hue to a and b: a = C × cos(H), b = C × sin(H). L stays the same.
  2. Oklab → linear sRGB. A short matrix multiplication followed by cubing intermediate values — Ottosson published the constants when he introduced Oklab.
  3. Linear sRGB → gamma-encoded sRGB. Apply the standard sRGB transfer curve (a piecewise gamma ~2.4).
  4. sRGB float → hex. Multiply by 255, round, and format as two hex digits per channel.

You do not have to implement this by hand. Browsers, design tools, and the conversion tool all do it for you. But understanding the pipeline matters because the second step is where colors can fall out of gamut.

What Happens When an OKLCH Color Is Out of sRGB Gamut

This is the single most important thing to understand. OKLCH can describe colors that simply do not exist inside sRGB — most commonly chroma values above ~0.32, depending on hue. When you convert one of those to hex, the conversion has to do something, and there are three common strategies:

  • Clamp. The naive approach — clip each RGB channel to 0–255 independently. Fast, sometimes ugly: hue can shift visibly when one channel saturates while the others do not.
  • Chroma reduction. Hold L and H constant, reduce C until the color falls inside sRGB. This is what modern browsers do via the CSS Color Module Level 4 gamut-mapping algorithm. The hue stays intact; only the saturation drops.
  • Closest-color mapping. Find the nearest in-gamut color by a perceptual distance metric. Most accurate, slowest, rarely used in real time.

The OKLCH picker follows the browser approach and will show you the clamped hex alongside a warning when you have crossed the gamut boundary. If the hex looks duller than the swatch above it, you have just hit gamut.

Going the Other Way: Hex to OKLCH

This direction is much simpler. Every hex color is, by definition, inside the sRGB gamut, so it maps to a unique OKLCH triplet with no clamping. The pipeline runs the same four steps in reverse: hex → sRGB float → linear sRGB → Oklab → OKLCH.

One quirk: small rounding noise. A hex value only has 8 bits per channel — about 0.4% precision. Converting #3A86FF to OKLCH and back returns #3A86FF on every well-implemented converter, but the OKLCH triplet you read on the way through has trailing digits you should not over-interpret. Three decimals on L and C, one decimal on H is more than enough precision for production tokens.

A Concrete Round-Trip

Take a vivid Hue Blender accent: #E63946 (a punchy red).

  1. Hex → OKLCH: oklch(0.622 0.222 24.8) — L 0.62, chroma 0.22, hue 24.8°.
  2. OKLCH → hex (round-trip): back to #E63946. Lossless.

Now nudge chroma upward to oklch(0.622 0.35 24.8) — outside sRGB. Converting this to hex through a browser-style gamut mapper yields roughly #FF1A2D with chroma silently pulled back to fit. The new color rendered to hex is no longer the same OKLCH triplet you asked for.

When You Should Convert, and When You Should Not

Convert OKLCH to Hex When:

  • You are exporting design tokens for native iOS or Android, where many tooling layers expect hex or RGB.
  • You are handing colors to a non-CSS context — email templates, SVG attributes that need older fallbacks, third-party SDKs.
  • You are documenting brand colors for marketing or print teams who do not work in CSS.
  • You are shipping CSS that needs to support browsers older than 2023 (the cutoff for OKLCH support). A static hex fallback is the lowest-risk pattern.

Stay in OKLCH When:

  • You are building a tonal scale (50–950) and need perceptually even lightness steps. The hex equivalents of a clean OKLCH ramp look messy and obscure the math you actually care about.
  • You are interpolating between two colors — in CSS gradients, animations, or theme transitions. Browsers can interpolate in oklch directly, avoiding the muddy gray midpoints you get in sRGB.
  • You are targeting wide-gamut Display P3 screens. OKLCH expresses P3-only colors directly; hex cannot.
  • You are tweaking contrast by adjusting only lightness. Doing this in hex requires guessing and re-checking; in OKLCH you change one number.

Most production CSS in 2026 follows a hybrid pattern:

:root {
  /* Brand tokens authored in OKLCH for design quality */
  --brand-500: oklch(0.62 0.22 25);
  --brand-700: oklch(0.42 0.20 25);

  /* Optional hex fallback for very old environments */
}

/* Fallback for non-CSS contexts (emails, native apps) lives in JSON tokens */

You author in OKLCH inside the browser. Your design-token pipeline (Style Dictionary, Tokens Studio, your own script) generates hex outputs for every non-CSS consumer. The single source of truth stays in OKLCH; hex becomes a build artefact.

Converting at the Command Line

If you script your token pipeline, the most ergonomic libraries are culori (JavaScript) and colorjs.io (cross-platform). Both implement the CSS Color Module Level 4 conversion exactly, including gamut mapping. The Hue Blender color converter uses the same algorithms, so a value generated in your build script will match what you see in the browser tool — no surprises.

Three Conversion Gotchas to Know

  • Hue 0 vs 360. Both mean red. Some libraries normalize, some do not. If a converter returns H = 0 and another returns H = 360 for the same color, they are the same — do not "fix" it.
  • Achromatic colors. Pure grays have chroma 0 and an undefined hue. Many converters report H = 0 or H = NaN. Both are valid. Avoid storing the hue for achromatic tokens — it is meaningless.
  • Alpha is independent. The OKLCH-to-hex conversion has nothing to do with alpha. oklch(0.6 0.2 25 / 0.5) becomes #E6394680 (or rgba(230, 57, 70, 0.5)) — the alpha tags along untouched.

Validating the Converted Color

Two final sanity checks every time you batch-convert OKLCH tokens to hex:

  • Re-run the resulting hex pairs through the contrast checker — gamut mapping can shift effective contrast slightly, especially on saturated colors near sRGB's edge.
  • Compare hex outputs side by side with the original OKLCH swatches on a calibrated screen. If a color jumps perceptibly, you likely had an out-of-gamut OKLCH original.

Key Takeaways

  • OKLCH-to-hex is lossy only when the source OKLCH is outside sRGB; hex-to-OKLCH is always lossless.
  • Out-of-gamut OKLCH gets gamut-mapped — modern browsers and converters preserve hue, reduce chroma.
  • Author tokens in OKLCH, export hex for non-CSS consumers via your build pipeline.
  • Use the color converter or OKLCH picker for interactive conversion; culori or colorjs.io for scripted pipelines.
  • Re-validate contrast (checker) on round-tripped colors near the sRGB boundary.

Try it yourself

Mix any colors with our Kubelka-Munk pigment simulation tool and get instant HEX, RGB, CMYK codes.

Open Mixer

Related Articles

Related Tools