OKLCH to HEX Color Converter
OKLCH gives perceptual control. HEX gives universal compatibility.
OKLCH is increasingly used in design systems and Tailwind v4 configurations to generate color palettes that are visually consistent across hue angles. Most color fields outside a browser stylesheet (Figma fill inputs, SVG color attributes, email HTML, design documentation) still accept only HEX or RGB. Converting OKLCH values to HEX bridges the gap between modern perceptual color design and the broad ecosystem of tools that have not yet adopted CSS Color Level 4 syntax.
How the conversion works
Converting OKLCH to HEX follows the reverse of the HEX-to-OKLCH pipeline. First, the OKLCH coordinates produce OKLab Cartesian values by computing a as C times cos(H in radians) and b as C times sin(H in radians). Second, OKLab converts to XYZ-D65 through a linear matrix multiplication. Third, another matrix multiplication transforms XYZ-D65 to linear sRGB. Fourth, the sRGB transfer function applies gamma correction to produce 0 to 255 integers, which the encoder then writes as two-digit hex pairs.1 The conversion is deterministic and reversible for any color within the sRGB gamut. Colors outside sRGB must be clamped to the gamut boundary before the final hex encoding step. Achromatic colors with chroma near 0 convert cleanly because the hue angle contributes nothing when C is zero.
Where this comes up
Tailwind v4 and CSS Color Level 4 design workflows generate palette values in OKLCH. When those values need to populate Figma styles, Storybook color tokens, or a style guide PDF, HEX is the expected format. Email HTML (which must support clients like Outlook that do not parse oklch()) requires fallback HEX values for every perceptual color. Any CI pipeline that validates color contrast ratios using tools expecting HEX or RGB input needs the OKLCH values converted to HEX before the accessibility check runs. Design documentation tools such as Zeroheight and Supernova accept only HEX in their color swatch fields, so a conversion step is required before pasting OKLCH tokens into component specifications.
Edge cases and rounding
OKLCH values with L above 1 or below 0 are out-of-range and should be clamped before conversion. Chroma values above the sRGB gamut boundary for a given hue and lightness produce RGB channels above 255 or below 0 after conversion; the tool clamps these to the 0–255 range, which may shift the perceived hue or lightness slightly.1For any oklch() value originally derived from a standard HEX color, the round-trip produces the original HEX, differing by at most 1 in one channel due to floating-point rounding in the intermediate OKLab step. The same rounding behavior applies to RGB and HSL round-trips: a shift of 1 unit in one channel is the normal floating-point tolerance and is not a sign of a conversion error.
When you need HEX fallbacks for older browsers
Providing a HEX fallback before an oklch() declaration is the standard pattern for supporting browsers that do not yet parse oklch(), and you can get a HEX fallback for every oklch() value in the converter. Write the declaration as two lines: --color-brand: #3b82f6; --color-brand: oklch(0.612 0.212 261.5);. Browsers that do not understand oklch() ignore the second line and use the HEX value. Modern browsers parse both and apply the oklch() value because it comes last. This pattern works without any JavaScript or build step, making it the simplest progressive enhancement strategy for OKLCH adoption.
Automating fallbacks with PostCSS
The postcss-oklch plugin automates HEX fallback insertion at build time. After Tailwind v4 generates CSS with oklch() values, PostCSS processes the output and inserts a HEX fallback before each oklch() declaration.2 Configure it in postcss.config.js with require("postcss-oklch")() in your plugin list. The plugin reads the oklch() value, converts it to the nearest HEX, and writes the fallback line. This approach keeps your source CSS clean while ensuring every oklch() declaration ships with a compatible fallback in the production build.
The same plugin also normalizes the source oklch() values, so a token written with extra decimal places keeps a consistent fallback across the stylesheet. That consistency matters when the build runs twice on different machines, because a fixed HEX fallback removes any chance of the two runs disagreeing on the legacy color. Treating the PostCSS step as part of the build rather than a manual paste also means the fallback can never drift out of sync with the oklch() value it sits beneath.
OKLCH to HEX for email HTML and SVG compatibility
Email HTML is the most format-constrained environment in front-end development. Outlook (the desktop Windows version) renders email using the Microsoft Word HTML engine, which does not support oklch(), color-mix(), or CSS custom properties. Every color in an email template must be expressed as a 6-digit HEX code in a style attribute or a td bgcolor attribute.3 Converting your OKLCH design tokens to HEX before writing email templates is a mandatory step, not an optional optimization.
SVG fill and stroke attributes
SVG fill and stroke attributes accept HEX and rgb() but not oklch() in most SVG rendering contexts. When you generate SVG icons or illustrations programmatically from a design token system that stores colors in OKLCH, convert to HEX before writing the SVG markup. The conversion is lossless for sRGB-gamut colors, so the SVG rendering matches the browser rendering of the same token. For inline SVG within an HTML document, you can use oklch() in a <style> block that targets SVG elements, since the HTML parser handles the CSS. Standalone .svg files served from a CDN need HEX.
Gamut checking before converting OKLCH to HEX
Not every OKLCH coordinate converts cleanly to HEX. Colors with chroma values above the sRGB gamut boundary for their hue and lightness produce RGB channels outside the 0 to 255 range after conversion. The tool clamps these to 0 or 255, which shifts the resulting color. Before converting an OKLCH value to HEX for production use, check whether the chroma is within the sRGB gamut at that lightness level. At L=0.5, most hues max out around C=0.15 in sRGB; at L=0.8, the maximum drops to roughly C=0.08.
Using the W3C gamut mapping algorithm
The W3C specification defines a gamut mapping algorithm that reduces chroma in OKLCH space until the color falls within the target gamut. This produces a perceptually close in-gamut color rather than a channel-clamped color with a shifted hue. CSS Color Level 4 references this algorithm for the gamut-mapping media feature. When you need to convert a wide-gamut OKLCH value to HEX, reducing chroma by 0.01 increments until all RGB channels fall within 0 to 255 produces a better result than clamping alone.
When to use this
Use this when an OKLCH value from a Tailwind v4 config, a CSS Color Level 4 palette, or an OKLCH design tool needs to be expressed as HEX for Figma, email HTML, SVG, or any system that does not yet accept oklch() natively.
Examples
Tailwind v4 palette value → Figma fill
oklch(0.960 0.241 128.2)
#c8ff00
Paste the HEX directly into Figma's color fill field.
OKLCH scale step → email HTML fallback
oklch(0.612 0.212 261.5)
#3b82f6
Use as the color attribute in email HTML for Outlook compatibility.
- 1.
Björn Ottosson, "A perceptual color space for image processing," bottosson.github.io, accessed June 2026. https://bottosson.github.io/posts/oklab/
- 2.
Jonathan Neal, "@csstools/postcss-oklab-function," npm, accessed June 2026. https://www.npmjs.com/package/@csstools/postcss-oklab-function
- 3.
Andrey Sitnik and Travis Turner, "OKLCH in CSS: why we moved from RGB and HSL," evilmartians.com, September 2025. https://evilmartians.com/chronicles/oklch-in-css-why-quit-rgb-hsl