How CSS OKLab Fixes Gradient Gray Dead Zones
The traditional CSS gradient often suffers from a muddy, desaturated
band known as the "gray dead zone" when transitioning between vibrant
complementary colors. This article explains why legacy sRGB
interpolation creates these dull intermediate shades and details how the
modern oklab color space resolves the issue by organizing
colors according to human visual perception, preserving lightness and
saturation across color stops.
The Origin of the Gray Dead Zone
When a browser renders a standard CSS gradient using
linear-gradient(blue, yellow), it historically defaults to
interpolating color values within the standard RGB (sRGB) color space.
In sRGB, colors are represented as numerical intensities of red, green,
and blue light channels.
When you transition between two opposing or complementary hues—such as blue and yellow, or cyan and orange—the math simply computes the midpoint of each channel. Because complementary colors occupy opposite extremes on the color wheel, their intermediate mathematical averages cancel each other out, driving the red, green, and blue values toward equivalent amounts. In additive color models, equal parts of low-to-medium red, green, and blue yield neutral gray or muddy brown. Consequently, the gradient experiences a severe dip in perceived brightness and saturation right in the middle of the transition.
How OKLab Solves the Problem
Introduced to CSS Color Module Level 4, OKLab is a perceptual color space designed by Björn Ottosson in 2020. Unlike sRGB, which models how digital screens emit light, OKLab models how the human visual system processes color.
OKLab represents colors using three coordinates:
- L (Lightness): Perceived brightness, ranging from 0 (black) to 1 (white).
- a (Green/Red): How green or red a color is along a Cartesian axis.
- b (Blue/Yellow): How blue or yellow a color is along a Cartesian axis.
OKLab eliminates the gray dead zone through three primary structural advantages:
1. Perceptual Uniformity
In sRGB, two colors with mathematically identical values can appear to have vastly different brightness levels to the human eye; for example, pure yellow appears far brighter than pure blue. OKLab corrects this by aligning its numerical scale with human perception. A straight line drawn between two colors in OKLab maintains an accurate, predictable trajectory of perceived lightness without unprompted dips into darkness.
2. Linear Lightness Interpolation
When transitioning between two colors in OKLab, the perceived lightness (\(L\)) changes linearly from the start point to the end point. If you transition between a light color and a dark color, the intermediate points transition smoothly in brightness rather than plummeting into an artificial, murky shadow at the midpoint.
3. Uniform Chroma and Hue Distribution
OKLab maps chromatic intensity (saturation) uniformly across hues. In standard sRGB, interpolating across opposite colors cuts straight through the low-saturation center of the color cube. While OKLab also transitions across hues, its perceptual calibration ensures that the transition minimizes the loss of chroma. Intermediate colors retain enough visual energy to avoid collapsing into flat, washed-out grays.
Using OKLab in Modern CSS
To prevent the gray dead zone, you can explicitly define the
interpolation color space using the in oklab syntax within
modern CSS gradients:
/* Legacy gradient: produces a muddy, gray middle */
.legacy-gradient {
background: linear-gradient(to right, #0000ff, #ffff00);
}
/* OKLab gradient: smooth, vibrant transition with no gray dead zone */
.vibrant-gradient {
background: linear-gradient(in oklab to right, #0000ff, #ffff00);
}By adding in oklab, the browser calculates every
intermediate pixel along the OKLab color axis before converting the
final values to the display's output space. This produces smooth,
visually natural transitions without requiring developers to manually
insert intermediate color stops to artificially maintain vibrancy.