Perceptual Uniformity

Why equal numbers should mean equal-looking steps, and how OKLCH delivers it.

A color space is perceptually uniform when equal moves in its coordinates produce equal-looking changes. It sounds abstract, but it is the single property that decides whether a generated palette looks professionally even or subtly broken.

The idea#

Human brightness perception is nonlinear: we are far more sensitive to differences between dark tones than between light ones (roughly following a cube-root law - the basis of CIELAB's L*). A space that ignores this, like raw RGB, wastes resolution where eyes can't see it and starves the shadows where they can.

Uniformity has two practical faces:

  • Within one axis - stepping lightness 0.1 at a time should produce ten visually even steps, not steps that bunch up in the middle.
  • Across hues - two colors with the same L should look equally light whether they are yellow or blue. HSL fails this badly; OKLCH is built for it.

Seeing it: two ten-step scales#

90%
82%
74%
66%
58%
50%
42%
34%
26%
18%
0.93
0.86
0.79
0.72
0.65
0.58
0.51
0.44
0.37
0.30
Two ten-step blue scales with mathematically even steps. Top: HSL lightness 90% → 18%. Bottom: OKLCH lightness 0.93 → 0.30. The HSL scale lurches - barely-different pale steps, then a cliff into saturated mid-blues; the OKLCH scale descends evenly.

This is exactly the defect Lumea's Lightness Progressionchart exposes: it plots each palette step's measured L against an ideal even ramp, so bunching shows up as a bowed line.

Measuring difference: ΔE#

Uniform spaces make distance meaningful: the further apart two colors sit, the more different they look. Color science calls that distance ΔE (delta-E). In OKLab, a useful rule of thumb (scaled ×100, as Lumea reports it):

ΔE (×100)Perception
< 2Effectively identical - most people can't tell them apart
2 – 10Distinguishable side-by-side; reads as the same 'color family'
10 – 25Clearly different shades
> 25Different colors outright

Lumea's Perceptual Distance Matrix computes ΔE for every pair in your palette. Two neighbours under ~7 are a warning: users will struggle to tell those steps apart in a chart legend or a hover state.

Where uniformity pays off#

  • Design-system scales- a 50→950 ramp generated by stepping OKLCH lightness stays even across every hue family, so “blue-600” and “green-600” feel like the same weight.
  • Programmatic states - hover/active variants derived by ±0.06 L look consistent on every accent color, with no per-color hand-tuning.
  • Data visualization - sequential color ramps encode magnitude honestly only if equal data steps produce equal perceived color steps.
  • Gradients & mixing - interpolating in a uniform space avoids the gray dead zones sRGB gradients suffer (covered in Color Mixing).

Further reading#