For decades, web designers and developers have been constrained by the limitations of sRGB and the awkwardness of HEX notation. We’ve all been there: staring at #3A7BD5 and trying to remember whether that’s the blue we wanted, or wrestling with RGB values that bear no resemblance to how we actually perceive colour. However, the landscape is changing, and OKLCH (Oklch colour space) represents perhaps the most significant advancement in how we define and manipulate colour on the web.
The problem with traditional colour spaces.
Let’s start with what we’ve been using. HEX codes, whilst compact, are essentially meaningless to the human eye. Can you tell me what #FF6B9D looks like without looking at it? Probably not. RGB and even HSL, whilst more intuitive than HEX, have their own shortcomings.
HSL (Hue, Saturation, Lightness) was a step forward. At least you could read hsl(200, 50%, 60%) and have some idea that you were looking at a medium-light blue. But HSL has a fundamental flaw: its lightness component isn’t perceptually uniform. A yellow at 50% lightness appears far brighter than a blue at the same 50% lightness. This makes creating harmonious colour palettes considerably more difficult than it should be.
RGB suffers from similar issues. It’s based on how screens emit light, not how humans perceive colour. This disconnect between the technical representation and our perception has real-world consequences when you’re trying to build accessible, visually coherent designs.
Perceptually uniform colour.
OKLCH (Oklab Lightness Chroma Hue) is built on the Oklab colour space, which was specifically designed to be perceptually uniform. What does this mean in practice? When you adjust the lightness value in OKLCH, the perceived brightness changes uniformly across all hues. A blue at 60% lightness will appear just as bright as a red at 60% lightness. This is transformative for designers.
The syntax is refreshingly straightforward: oklch(60% 0.15 250). That’s lightness (0-100%), chroma (roughly equivalent to saturation, typically 0-0.4), and hue (0-360 degrees). Just like HSL, you can read this and immediately understand what you’re looking at, but unlike HSL, the values actually correspond to how you perceive the colour.
Unlocking Display P3.
Perhaps the most exciting aspect of OKLCH is its native support for wide-gamut colours. The sRGB colour space, which has been the web’s standard since the 1990s, can only represent about 35% of the colours visible to the human eye. Modern displays—particularly phones, tablets, and high-end monitors—support Display P3, which encompasses roughly 50% of visible colours.
With OKLCH, you can specify colours that exist beyond the sRGB gamut. That electric cyan you’ve been trying to achieve? The vibrant coral that always looks slightly muted? These colours are now accessible. And here’s the clever bit: if a display doesn’t support Display P3, OKLCH automatically falls back to the nearest sRGB colour. Your designs remain functional whilst taking advantage of better displays where available.
Try achieving this with HEX or standard RGB notation, and you’ll quickly find yourself in a world of colour profile conversions and browser inconsistencies.
Comparing modern alternatives.
It’s worth examining how OKLCH stacks up against other modern colour spaces now available in CSS:
Display P3
Display P3 is a colour space, not a notation. You can write color(display-p3 1 0.5 0.3), but these RGB-style values suffer from the same perceptual non-uniformity as sRGB. You’re working with wider colours, but you’re still guessing at the results.
LCH
LCH (Lightness Chroma Hue) was a significant step forward and shares OKLCH’s human-readable format. However, it’s based on the older CIELab colour space, which has some perceptual quirks. Blues tend to appear darker than they should, and certain hue transitions can look uneven. OKLCH, based on the newer Oklab, corrects these issues.
LAB and Oklab
LAB and Oklab are powerful but less intuitive. Working with values like lab(60% 20 -40) requires understanding what positive and negative values mean for red-green and blue-yellow opponent channels. For most design work, the polar coordinate system of OKLCH (with its explicit hue angle) is far more practical.
Practical benefits in real-world work.
The advantages of OKLCH extend beyond theory into everyday design tasks:
Colour palettes become trivial to create.
Need a lighter version of your brand colour? Increase the lightness value. Want a desaturated variant? Reduce the chroma. The perceptual uniformity means these adjustments work consistently across your entire palette.
Gradients maintain their vibrancy.
Anyone who’s created a gradient from yellow to blue knows the muddy grey that appears in the middle. OKLCH gradients maintain colour vibrancy throughout the transition because the interpolation happens in a perceptually uniform space. To ensure your gradient interpolates in OKLCH, simply specify it in the gradient declaration:
background: linear-gradient(in oklch,
oklch(80% 0.15 60),
oklch(70% 0.189 240)
);
The in oklch keyword tells the browser to perform the colour interpolation in the OKLCH colour space, ensuring smooth, vibrant transitions even when mixing colours defined in other formats.
Accessibility improvements are more predictable.
When contrast ratios are calculated based on perceived lightness, and your colour space accurately represents perceived lightness, ensuring sufficient contrast becomes more straightforward. The lightness value in OKLCH directly correlates to how bright text or backgrounds will appear.
Systematic colour generation becomes possible.
You can programmatically generate entire colour schemes by varying OKLCH parameters whilst maintaining visual harmony. This is invaluable for design systems, theming, or any project requiring consistent colour variations.
Browser support and progressive enhancement
At the time of writing, OKLCH enjoys excellent support in modern browsers. Safari, Chrome, Edge, and Firefox all support OKLCH, covering the vast majority of users. If you must support older browsers, progressive enhancement is straightforward: provide an sRGB fallback, then specify your OKLCH value. Browsers that don’t understand OKLCH will ignore it and use the fallback.
.element {
background: #1483dc; /* Fallback */
background: oklch(0.6 0.163 250); /* Modern browsers */
}
This is the beauty of CSS: it’s designed for exactly this kind of graceful degradation.
Making the switch
Transitioning to OKLCH doesn’t require rebuilding everything overnight. You can adopt it incrementally, starting with new projects or specific components. Tools like colour converters can help translate existing palettes, though you’ll likely find yourself rethinking some colour choices once you see what’s possible.
The learning curve is minimal if you’re already comfortable with HSL. The syntax is similar, the values are human-readable, and the results are more predictable. It’s simply a better tool for the job.
OKLCH represents a fundamental improvement in how we work with colour on the web. It combines human-readable syntax with perceptual uniformity and wide-gamut support, solving problems that have plagued designers since the web’s inception. As displays continue to improve and users expect more vibrant, engaging experiences, OKLCH is here, well-supported, and it’s the pragmatic choice for modern CSS.
