Light and the eye
Visible light is the thin slice of electromagnetic radiation between roughly 380 and 750 nanometres. A light source has a spectrum — power at every wavelength — and a surface has a reflectance curve. What reaches your eye is their product.
The retina samples that light with three kinds of cone cell: L, M and S, peaking around 560, 530 and 420 nm. Everything you will ever see as colour is compressed into those three responses — which is why three numbers are enough to describe a colour, and why three primaries are enough to fake one.
Trichromacy and metamerism
Thomas Young proposed three kinds of receptor in his 1802 Bakerian Lecture; Hermann von Helmholtz developed the idea in 1850, and in 1857 James Clerk Maxwell gave the Young–Helmholtz theory a mathematical footing. The consequence is metamerism: two physically different spectra that produce the same three cone responses look identical. Your monitor depends on it — its red, green and blue sub-pixels produce a spectrum nothing like a lemon, yet the cones cannot tell.
Metamerism is also why two fabrics can match in the shop and clash in daylight: change the illuminant and the products with each reflectance curve diverge.
CIE 1931 and XYZ
In 1931 the Commission Internationale de l'Éclairage standardised the results of Wright's and Guild's matching experiments as three colour-matching functions x̄(λ), ȳ(λ), z̄(λ). Integrating a spectrum against them gives the tristimulus values X, Y, Z. They were chosen so that all values are positive and Y equals photometric luminance.
Divide out the brightness and you get chromaticity: x = X / (X+Y+Z), y = Y / (X+Y+Z). Plot every pure wavelength and you trace the famous horseshoe — explore it on the Chromaticity page. Any colour made by mixing two lights lies on the straight line between them, which is why each RGB display covers a triangle.
RGB, primaries and gamma
An RGB space is fully defined by three things: the chromaticities of its primaries, a white point, and a transfer function. sRGB (HP & Microsoft, 1996) uses the Rec. 709 primaries, the D65 white point, and a curve of roughly gamma 2.2.
Arithmetic on light — blending, blurring, resizing — must happen on linear values. Averaging encoded values is why naive gradients and downscaled images often look too dark.
HSL, HSV and why they lie
HSV and HSL (both 1978) re-arrange the RGB cube into cylinders so people can think in hue, saturation and lightness. They are geometric conveniences, not models of perception. Both swatches below are hsl(… 100% 50%) — identical “lightness”:
Their CIELAB lightness differs by more than 60 points. Use a perceptual space whenever lightness matters — accessible palettes, data visualisation, gradients.
CIELAB: measuring what we see
In 1942 David MacAdam showed that the colours people cannot tell apart form ellipses on the xy diagram, and that their size and orientation vary widely from one colour to another. Equal distances in xy are not equal differences to the eye. CIELAB (1976) warps XYZ to fix this: a cube-root compression mimics the eye's response, and three opponent axes mirror how the visual system encodes colour.
Opponent channels echo Ewald Hering's opponent-colour theory (1892): nobody reports a reddish green or a yellowish blue, because red–green and blue–yellow behave as two ends of the same signal. Slice CIELAB on the Lab Matrix page or orbit it in 3D.
ΔE: how different is different?
The colour difference ΔE*76 is simply the straight-line distance in CIELAB. Every ΔE formula is designed so that 1.0 stands for roughly one just-noticeable difference, although for ΔE*76 the JND was later put at about 2.3. CIELAB is not perfectly uniform, especially in the blues, so the formula was revised: ΔE*94 weights chroma and hue, and CIEDE2000 (published 2001) adds a rotation term for the blue region, a lightness weighting and a chroma correction for near-neutrals.
A common industry rule of thumb — not a standard — reads ΔE00 below 1 as imperceptible, 1–2 as visible on close inspection and above 10 as clearly different colours. Try it on Contrast & ΔE.
OKLab and the modern web
In December 2020 Björn Ottosson published OKLab: a simple space — one matrix, a cube root, another matrix — designed to fix CIELAB's unexpected hue and lightness shifts in the blues. Desaturate a vivid blue in CIELAB LCh and it drifts toward purple (see below); OKLCH holds the hue. oklab() and oklch() are part of CSS Color 4, which also specifies OKLCh for gamut mapping and OKLab as the default space for gradient interpolation. See the difference on the Gradients page.
Color harmony: a short history
Classical harmonies — complementary, analogous, triadic, split-complementary, tetradic — are geometric rules on a wheel. They are useful starting points rather than laws: colour-theory reviews note that such formulae have limited practical application. Which wheel you use also changes the result: RYB puts violet opposite yellow, RGB puts blue there. Try both on the Harmony wheel.
Simultaneous contrast
Chevreul noticed that a colour shifts away from its surroundings. The two small squares below are exactly the same grey:
This is why a colour picked in isolation never looks the same in a layout — and why legibility metrics like WCAG and APCA compare a pair of colours, not one.
Color vision deficiency
About 8% of men and 0.5% of women of Northern European ancestry have a red–green deficiency: a missing or shifted L cone (protan) or M cone (deutan). Deuteranomaly alone affects about 5% of men. Blue–yellow (tritan) defects affect fewer than 0.01% of people, and complete achromatopsia is rarer still. Simulations such as Machado, Oliveira & Fernandes (2009) project colours into the reduced space a dichromat can see — run any image through them on the Image Lab.
Practical rule: never let hue be the only difference. Pair colour with lightness contrast, shape, labels or texture.
Glossary
- Hue
- The attribute by which a colour is called red, yellow, green, blue…
- Chroma
- Colourfulness relative to a white of the same brightness. Saturation is colourfulness relative to the colour's own brightness.
- Lightness
- Brightness relative to a white. L* and OKLab L model it.
- Luminance
- Photometric light weighted by the eye's sensitivity (CIE Y). Physical, linear.
- White point
- The chromaticity treated as neutral — D65 (daylight, 6504 K) for screens, D50 for print.
- Gamut
- The set of colours a device or space can produce.
- Chromatic adaptation
- The eye's white balance; modelled by transforms such as Bradford when converting between white points.
- Metamers
- Different spectra that look identical to a given observer under a given light.
- CCT
- Correlated colour temperature: the black-body temperature whose colour is closest to a light source.
Sources
The text on this page is original writing, fact-checked against the references below. Numbers in the figures are computed live from the same formulas the tools use.
- Wikipedia: Visible spectrum, Cone cell, Young–Helmholtz theory, Metamerism, CIE 1931 color space, Luminous efficiency function, sRGB, HSL and HSV, MacAdam ellipse, CIELAB color space, Opponent process, Color difference, Oklab color space, Color wheel, Color theory, Michel Eugène Chevreul, Munsell color system, Johannes Itten, Josef Albers, Color blindness.
- CIE 1931 2° standard observer, 1 nm table (CIE 018:2019), via the colour-science library.
- W3C CSS Color Module Level 4 — conversion matrices, D50 Lab with Bradford adaptation, gamut mapping, interpolation.
- IEC 61966-2-1:1999 (sRGB) · ITU-R BT.709 and BT.2020.
- B. Ottosson, “A perceptual color space for image processing” (2020).
- G. Sharma, W. Wu, E. Dalal, “The CIEDE2000 color-difference formula: implementation notes”, Color Research & Application 30 (2005).
- G. Machado, M. Oliveira, L. Fernandes, “A physiologically-based model for simulation of color vision deficiency”, IEEE TVCG 15 (2009).
- C. S. McCamy, “Correlated color temperature as an explicit function of chromaticity coordinates”, Color Research & Application 17 (1992).
- WCAG 2.2 contrast criteria (W3C) · APCA 0.0.98G-4g (Myndex).