How one engineer's blog post changed colour on the web
Tim Knowles (opens in a new tab)11 min read
Oklab is the colour maths behind OKLCH, and it started life as a free blog post. Björn Ottosson, a Swedish engineer who had just left the games industry, put it online on 23 December 2020. Nine days later an Apple engineer had flagged it to the W3C. Within ten months CSS had voted it in, Photoshop made it the default that same month, and by May 2023 every major browser had it.
Try out the 1976 maths and the 2020 maths on blue
At 50% white: 1976 maths gives #AF89FF, 2020 maths gives #74A3FF.
Read a hex code in pairs: red, green, blue. In the 1976 maths the red pair overtakes the green pair, and the blue reads as lavender. In the 2020 maths green stays ahead, and it reads as sky blue.
These strips are drawn from computed hex codes.
For the curious
The 1976 maths is CIELAB, used here in its lightness, chroma and hue form (CIE LCh), the same as CSS color-mix(in lch, …). The 2020 maths is Björn Ottosson’s Oklab, in the same form (OKLCH), as color-mix(in oklch, …). The plain mix averages the sRGB numbers, as color-mix(in srgb, …).
Some of the 1976 mixes land just outside what a screen can show. The hex codes bring them back in the way the CSS spec says browsers should, which is why they match the article. Other colour libraries do this step differently and can land a few units away.
Why did lighter blues use to turn purple?
You've lightened your brand blue for a button, and somewhere on the way to white it's gone lavender. With the older colour maths, a strong blue does exactly that. Mix pure blue halfway to white using CIELAB, the 1976 standard, and you get #AF89FF, which is a soft lilac. Do the same mix with Ottosson's 2020 maths and you get #74A3FF, a clear sky blue. The 1976 maths keeps the hue number steady, but your eye still sees the colour bend.
Picture a straight road drawn on a map that's been stretched near one corner. On paper the road is dead straight, whereas on the ground it curves. The older colour maths stretched the map around blue, so every tool built on it inherited the curve. Lighter versions of a colour without it turning purple explains how that works. This article is about the man who redrew the map, and the people who carried his drawing into every browser.
Who is Björn Ottosson?
He's a software engineer in Stockholm, and for a bit more than a decade, until 2020, he worked at DICE on the Frostbite game engine. That's the technology behind games like FIFA, Battlefield and Need for Speed. Oklab came after he left. As he put it to Smashing Magazine, once he moved out of gaming and into teaching and consulting, he finally had some time.
He built it in his free time, unpaid, with no employer involved. The itch did come from his games work, though. Now and then he'd want to make a simple change, like darkening a colour or shifting its hue, and the colour would go wrong.
On 3 December 2020 he posted "How software gets color wrong", which set out the problem and promised more posts to follow. Three weeks later, two days before Christmas, the follow-up arrived.
What the blog post actually did
The follow-up was "A perceptual color space for image processing" (opens in a new tab), and it gave a short formula that sorts colours so equal steps look roughly equal. He'd looked at every existing option for that job and judged them all to have serious drawbacks. CIELAB, in his words, was worst at hue, especially blues.
His recipe was a practical one. The best model of how colours look, called CAM16, is accurate but heavy to run. So he took the simple shape of an older, lighter colour space and tuned it until it gave nearly the same answers as CAM16 for lightness and colourfulness. For hue, he borrowed measured data from that older space's own study. The whole conversion runs to about ten lines of code.
Then he did something you don't often see. He'd wanted the original experiment data behind CAM16 but couldn't find it, so he generated his targets from the model instead, and he said so. In the post he warned that this generated data can't prove which model best matches human vision. And on his own scoreboard, Oklab wins on lightness and colourfulness but not on hue. Its win is balance and simplicity.
Worth knowing: the blue problem was measured long before Oklab. In 1995 Hung and Berns had nine people judge colours on a CRT monitor, and they found large errors in CIELAB near the screen's pure blue. So the lavender drift was a known, measured fault a full 25 years before Oklab came along.
Why is it called Oklab?
Because he was being modest. He wrote that he called it that "because it is an OK Lab color space". Lab is the family name for colour spaces like CIELAB, and the "OK" is the claim: good, not perfect.
Talking to Smashing, he called the name tongue-in-cheek, and added "I didn't want to call it Björn Ottosson Lab." OKLCH is the same space again, just described by lightness, colourfulness and hue. So whatever a chatbot may have told you, "OK" is not an acronym.
From blog post to the W3C in nine days
Oklab spread because it was short and free, and because it fixed something people could see. He released the code into the public domain, then added an MIT licence option in early January 2021. And on 24 December 2020, about 25 hours after the post went up, a JavaScript colour library called culori had already shipped it.
Then came New Year's Day 2021. Simon Fraser, from Apple's WebKit team, tweeted the post to Chris Lilley at the W3C, the body that writes web standards, with a short question: "A candidate for CSS colors?" Lilley's own account credits that tweet with putting Oklab on his radar. On 18 January, Raph Levien published an independent interactive review (opens in a new tab) that recommended Oklab for better gradients, with some reservations.
By July 2021 Lilley was giving a talk at a W3C workshop (opens in a new tab) asking whether Oklab was better than the 1976 maths. At the end he answered Fraser's question: "yes, basically". Ottosson says none of this needed him to promote it. It just happened.
The vote at the CSS working group
The formal proposal came from Lilley on 20 September 2021, in issue 6642 (opens in a new tab), and the debate that followed was quick and good-natured. On 6 October Lea Verou first called it "a little premature". But five hours later, after Lilley argued that CSS needed it internally anyway, she was in favour. Tab Atkins joked about the name: "just ok? Pass." Both of them are named as editors of the colour spec in its current draft, alongside Lilley.
On 13 October 2021 the working group passed six resolutions in a single call. They added oklab() and oklch() to CSS, made Oklab the default for blending colours written in the newer syntax, and chose OKLCH for pulling colours that are too vivid for a screen back into range. Simon Fraser was on that call. And at that point, as someone noted, no operating system used Oklab yet, only colour libraries.
Four days later Ottosson joined the thread himself. "I didn't expect it to become so widespread so quickly", he wrote. He floated a possible revision too, while noting that any change would break things for the people already using it. As far as I can find, no revised Oklab was ever published.
A side note: the web's Oklab is the same as Ottosson's. The CSS spec tidied the far decimals of his numbers so that white comes out exactly neutral, but in our checks the gap is about 160 times smaller than the smallest difference anyone could see. His core formula never changed. A small update on 25 January 2021 only refined his shortcut numbers after the third decimal.
See the road from blog post to every browser
- Blog post
Björn Ottosson’s “How software gets color wrong” sets out the problem.
- Blog post
He publishes Oklab, free for anyone to use.
- Code library
culori, a JavaScript colour library, ships it about 25 hours later.
- Tweet
Simon Fraser of Apple’s WebKit team tweets it to Chris Lilley at the W3C.
- Talk
Lilley asks a W3C workshop if it beats the 1976 maths. His answer: “yes, basically”.
- Standards
The CSS working group votes oklab() and oklch() into CSS.
- Design tool
Photoshop’s October 2021 release makes Oklab-based “Perceptual” gradients the default.
- Browser
Safari 15.4 ships it, the first browser to do so.
- Browser
Chrome and Edge 111 ship it.
- Browser
Firefox 113 ships it. Every major browser now has it.
- Framework
Tailwind CSS v4 moves its whole default palette to OKLCH.
- Blog post
Ottosson adds an introduction headed “From personal project to industry standard”.
- Standards
Not everything moved: CSS keeps gradients written in hex blending the old way.
From the post to every major browser: 867 days, or about 2 years and 4½ months.
Photoshop got there before the browsers
Photoshop's October 2021 release made "Perceptual" gradients the new default, which was the same month as the CSS vote. Adobe's help page (opens in a new tab) says the Perceptual mode uses Oklab. So Photoshop had it about five months before any browser shipped it.
Among the browsers, Safari was first, in March 2022 (version 15.4). Chrome and Edge 111 followed in March 2023, then Firefox 113 on 9 May 2023. That meant every major engine had it, about two and a half years after the post. It has counted as "Baseline widely available" since 9 November 2025.
Other tools followed. Unity 2022.2 added an optional Oklab gradient mode in December 2022. Godot 4.0 added a colour picker mode in March 2023, built on Okhsl, a later space Ottosson based on Oklab. Evil Martians' article "OKLCH in CSS" (opens in a new tab), first out in autumn 2022, took it to front-end developers. Sass added oklab() and oklch() in September 2024. Then on 22 January 2025, Tailwind CSS v4 (opens in a new tab) moved its entire default palette to OKLCH.
Why does a web standard cite a blog post?
Because there was never a paper to cite. CSS Color Module Level 4 (opens in a new tab) lists Ottosson's post as a normative reference, which means the standard depends on it. It has done since its first draft with Oklab, on 15 December 2021, and it still does in the draft of 13 September 2026. Peer-reviewed papers now cite the post as well. As far as I can find, he never published Oklab as a paper at all.
It's a good recipe, posted free online, and short enough to copy onto a card. But the middle step matters. People inside the W3C proposed it, argued it through and wrote the spec text, so the blog post didn't become a standard by itself.
What the "OK" doesn't promise
Oklab is approximately even, not perfectly even, and that's exactly what "OK" means. Its targets were generated from another model, and its hue data covered just 15 hues, as Ottosson himself pointed out on Hacker News. In a later post he went further and wrote that it's "not possible to have a lightness scale that is perfectly uniform" in every viewing condition.
It also deliberately ignores the background and the room, even though both change how a colour looks (see The same colour looks different in different places). Levien's review flagged weak spots at the dark end, and pointed out that tuning to an existing model keeps that model's flaws. And because Oklab starts from the 1931 standard observer, it inherits that averaged 1920s eye.
Not everything moved over, either:
| Where | Still on the old maths? | As of |
|---|---|---|
CSS gradients written with hex, named, rgb() or hsl() colours | Yes, by rule. The working group voted to switch them in 2023, then reversed that on 4 June 2025 over compatibility and speed. | 13 Sep 2026 spec |
CSS color-mix() | No. The spec default is now Oklab (agreed 19 August 2025). Safari 26.2 shipped it first. | Dec 2025 |
| Chrome's automatic dark mode | Yes. It still flips lightness with CIELAB. | 23 Sep 2026 code |
| Figma | No native Oklab or OKLCH. The request has been open since March 2022. | 15 Sep 2026 staff reply |
In May 2025, Ottosson added an introduction to his post headed "From personal project to industry standard". In it he says he never expected it to reach as far as it has, and he asks, gently, for support from the people who use it. He made it unpaid, he gave it away, and he called it OK.
What should you do differently in your next design?
Use the 2020 maths wherever you can, and know where the old maths is still hiding.
- Lighten blues in OKLCH, not HSL or CIELAB. Tools built on this maths, Tailwind v4's palette among them, lighten blue without the lavender drift. So if a tint of your brand blue looks lilac, check which maths made it.
- Write gradients in the newer colour syntax if you want them to blend in Oklab. Hex gradients in CSS still blend the old way. Why your gradient goes muddy in the middle shows how.
- Don't treat "perceptually uniform" as a promise. Check your steps by eye, on the real background, especially with very vivid colours. Why "same brightness" colours don't look the same covers the catch with vivid colours.
- Expect a conversion step between Figma and code. As of September 2026 Figma has no native OKLCH, whereas every major browser has supported it since May 2023.
- Credit it properly. It's Björn Ottosson's Oklab, from his 2020 blog post, and "OK" means OK.
Frequently asked questions
What does the "OK" in Oklab and OKLCH stand for?
Nothing, it's a modest joke. Björn Ottosson, who published Oklab in December 2020, named it that because it is "an OK Lab color space", which means a good improvement on the older CIELAB but not a perfect one. He has called the name tongue-in-cheek himself. OKLCH is the same space, described by lightness, colourfulness and hue. So expansions like "Optimal Color" that you'll see online are made up.
For the curious
The 1976 maths is CIELAB (and its cylindrical form, LCh). Oklab keeps the computational structure of IPT (Ebner and Fairchild, 1998) and is fitted to behave like CAM16-UCS (Li et al., 2017) on lightness and chroma, using IPT's hue data. Ottosson measured the fit with CIEDE2000, the standard colour-difference formula covered in How different do two colours need to be?.
The conversion starts from CIE 1931 XYZ with a D65 white point (see The 1920s experiment behind every screen colour). It is a 3×3 matrix to cone-like signals, a cube root on each, then a second 3×3 matrix to L, a and b. OKLCH is the polar form: lightness, chroma, hue.
CSS uses OKLCH for gamut mapping, lowering chroma at constant lightness and hue. The 2023 all-gradients resolution and its revert are in issue 7948; the spec's changelog cites it as "7949", a typo. Our blue-to-white hexes agree across five implementations, including the spec's own sample code, using CSS's gamut method.
Sources (19)
- Björn Ottosson, "A perceptual color space for image processing" (opens in a new tab), 23 December 2020 (2025 introduction added 26 May 2025)
- Björn Ottosson, "How software gets color wrong" (opens in a new tab), 3 December 2020
- Björn Ottosson, "Two new color spaces for color picking: Okhsv and Okhsl" (opens in a new tab), 8 September 2021
- Björn Ottosson, About (opens in a new tab)
- Philip Jägenstedt, "Interview With Björn Ottosson, Creator Of The Oklab Color Space" (opens in a new tab), Smashing Magazine, 2 October 2024 (translated from Swedish)
- Simon Fraser, tweet to @svgeesus, 1 January 2021 (Wayback Machine capture)
- Chris Lilley, "Better than Lab? Gamut reduction CIE Lab & OKLab" (opens in a new tab), W3C Workshop on Wide Color Gamut and HDR for the Web, July 2021
- Raph Levien, "An interactive review of Oklab" (opens in a new tab), 18 January 2021
- CSS Working Group, "[css-color] Add OKLab, OKLCH", issue 6642 (opens in a new tab), September–October 2021, and resolutions of 13 October 2021 (opens in a new tab)
- CSS Working Group, issue 7948 (opens in a new tab), revert resolved 4 June 2025
- W3C, CSS Color Module Level 4 (opens in a new tab), Candidate Recommendation Draft, 13 September 2026
- Adobe, "Gradient interpolation in Photoshop" (opens in a new tab), and Photoshop feature summary, October 2021 release
- MDN,
oklch()(opens in a new tab), and browser-compat-data, read 23 September 2026 - Tailwind Labs, "Tailwind CSS v4.0" (opens in a new tab), 22 January 2025
- A. Sitnik and T. Turner, "OKLCH in CSS: why we moved from RGB and HSL" (opens in a new tab), Evil Martians
- P.-C. Hung and R. S. Berns, "Determination of constant hue loci for a CRT gamut…" (opens in a new tab), Color Research & Application 20(5), 1995 (abstract)
- F. Ebner and M. D. Fairchild, "Development and testing of a color space (IPT) with improved hue uniformity" (opens in a new tab), IS&T CIC6, 1998 (abstract)
- culori 0.18.0, npm registry, 24 December 2020
- Figma Forum, "support oklab and oklch", staff reply 15 September 2026
Next: The 1920s experiment behind every screen colour
Tim Knowles
Websites, marketing strategy and AI training
Tim has worked in marketing since 2000. At Your Marketing Specialist he builds the websites, and colouriser is one of them. He is self-taught, and learns each subject in depth before he advises on it.
Each Article is written from Tim's own research, and every Figure runs on colouriser's own colour maths.
More about Tim (opens in a new tab)