Glossary

Oklab

Oklab is a perceptual color space that describes a color by lightness L and two opponent axes a and b, designed by Björn Ottosson in 2020 to make blends and lightness predictable. CSS Color Module Level 4 supports it through the oklab() function and its polar form oklch(). The number people look up most is the range: L runs from 0 to 1, and a and b stay roughly within plus or minus 0.4.

How it works

Oklab starts from linear-light sRGB, not gamma-encoded values. Three steps turn it into a Lab-style triple.

  • Mix to cone-like responses: a 3x3 matrix converts linear RGB to three values called l, m and s.
  • Compress: each value goes through a cube root, which is why equal numeric steps look more even than in linear light.
  • Mix again: a second 3x3 matrix produces L, a and b.

L is perceived lightness, where 0 is black and 1 is diffuse white. Positive a is a purplish red and negative a is green. Positive b is yellow and negative b is blue or violet. In CSS, percentages map 100% to L = 1 and to a or b = 0.4. The illuminant is D65, the same white point as sRGB, so no chromatic adaptation step is needed.

Ottosson fitted the matrices numerically against a large set of colors that look alike, aiming for good hue linearity, hue uniformity and chroma uniformity. Unlike CIE Lab, Oklab assumes adaptation to the color being defined rather than to a fixed white, so scaling a color's brightness keeps its hue and chroma consistent. Because it is more uniform, CSS Color 4 notes that color difference can be a plain straight-line distance, called deltaEOK.

const toLin = v => { v /= 255; return v <= 0.04045 ? v / 12.92 : ((v + 0.055) / 1.055) ** 2.4; };
function srgbToOklab(r, g, b) {
  const [R, G, B] = [r, g, b].map(toLin);
  const l = Math.cbrt(0.4122214708 * R + 0.5363325363 * G + 0.0514459929 * B);
  const m = Math.cbrt(0.2119034982 * R + 0.6806995451 * G + 0.1073969566 * B);
  const s = Math.cbrt(0.0883024619 * R + 0.2817188376 * G + 0.6299787005 * B);
  return [0.2104542553 * l + 0.7936177850 * m - 0.0040720468 * s,
          1.9779984951 * l - 2.4285922050 * m + 0.4505937099 * s,
          0.0259040371 * l + 0.7827717662 * m - 0.8086757660 * s];
}
const f = a => a.map(v => v.toFixed(4)).join(' ');
console.log('oklab(' + f(srgbToOklab(255, 255, 255)) + ')  white');
console.log('oklab(' + f(srgbToOklab(255, 0, 0)) + ')  red');
console.log('oklab(' + f(srgbToOklab(128, 128, 128)) + ')  gray 128');
console.log('oklab(' + f(srgbToOklab(59, 130, 246)) + ')  #3b82f6');
oklab(1.0000 0.0000 0.0000)  white
oklab(0.6280 0.2249 0.1258)  red
oklab(0.5999 0.0000 0.0000)  gray 128
oklab(0.6231 -0.0332 -0.1851)  #3b82f6

What is the difference between Oklab and OKLCH?

OKLCH is the same space in polar form: L stays the same, chroma C is the distance sqrt(a squared plus b squared), and hue H is the angle of a and b in degrees. For sRGB red the run above gives oklch(0.6280 0.2577 29.23). Use oklab() for math and mixing, and oklch() when you want to rotate hue or set chroma by hand.

Is Oklab the default for CSS gradients and color-mix?

For new color syntax, yes: CSS Color 4 says that when the host syntax does not name an interpolation space, it defaults to Oklab. Legacy sRGB formats such as hex, named colors, rgb() and hsl() are the exception and still interpolate in gamma-encoded sRGB for web compatibility. Writing color-mix(in oklab, ...) or a gradient with in oklab asks for it explicitly.

Common pitfalls

  • Mixing up scales with Lab: Lab lightness runs 0 to 100, Oklab L runs 0 to 1. Passing 54 to oklab() gives a color clamped to white, not a mid tone.
  • Feeding gamma-encoded values: the matrices expect linear-light RGB. Skipping the sRGB decode shifts every result, and mid grays such as 128 land at the wrong L.
  • Assuming every value is displayable: many L, a and b triples lie outside sRGB and must be gamut mapped, or they are clipped.
  • Expecting sRGB gray to equal L = 0.5: sRGB 128 gray is L of 0.5999 here. Perceptual lightness is not the same as the gamma-encoded number.
  • Comparing to Lab numbers: values from Lab and Oklab are not interchangeable, even for the same sRGB color, because the white point and the model differ.

Related terms

  • Lab color — the older CIE space Oklab improves on for hue and chroma uniformity
  • RGB — the additive model Oklab is converted from
  • HSL — a simpler model whose lightness is not perceptual
  • sRGB — the screen space whose linear values feed the Oklab matrices
  • HSV — another device-based model, built from the RGB cube

See also