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#
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 |
|---|---|
| < 2 | Effectively identical - most people can't tell them apart |
| 2 – 10 | Distinguishable side-by-side; reads as the same 'color family' |
| 10 – 25 | Clearly different shades |
| > 25 | Different 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).