You pick a deep blue and a vivid orange, paste them into a linear-gradient, and
the browser renders a murky brown smear in the middle. The colors looked great on their own
— so what went wrong?
This is the gray dead-zone: an artifact of how CSS blends colors by default. It shows up most aggressively when your two endpoint colors sit on opposite sides of the color wheel. The good news is that there are four practical fixes, each one better suited to a different situation. Here they all are.
Why the Gray Happens
A CSS gradient with no extra instructions interpolates in the sRGB color space. sRGB mixes color by linearly walking each of the red, green, and blue channels separately. When two colors have high saturation but point in opposite directions on the hue wheel (think blue at roughly 240° and orange at roughly 30°), the midpoint in raw RGB space lands near equal amounts of red, green, and blue — which is a gray or brown.
Technically: the colors have high chroma (colorfulness), but the straight-line path between them in sRGB cuts through the center of the color solid, where chroma is close to zero. The browser has no reason to avoid that desaturated zone — it just walks the shortest path in the model it was given.
The result is predictable: any two colors that are roughly complementary will produce a gray band in a plain sRGB gradient. There are four ways to escape it.
Fix 1: Use Analogous Colors
The simplest fix is to choose colors that sit close together on the hue wheel. Adjacent hues — blue to teal, pink to orange, violet to blue — never cross through the desaturated center of sRGB space because the straight-line path between them stays within a high-chroma arc.
/* Blue → Teal: clean, stays vivid the whole way */
background: linear-gradient(135deg, #0057ff, #00c5a6);
/* Orange → Pink: warm, no gray */
background: linear-gradient(135deg, #ff6b00, #ff3d8a); This approach requires no browser quirks and works everywhere. The trade-off is creative: you cannot use complementary color pairs without one of the other fixes below.
Fix 2: Add a Midpoint Color Stop
If you want to keep your two endpoint colors but avoid the gray midpoint, insert a vivid intermediate stop at or near the 50% position. You are manually overriding what the browser would have blended — placing a saturated color exactly where the default path goes gray.
/* Without fix: blue → [gray] → orange */
background: linear-gradient(135deg, #0057ff, #ff6b00);
/* With midpoint stop: blue → purple → orange */
background: linear-gradient(135deg, #0057ff, #8800ff 50%, #ff6b00); The trick is choosing the right midpoint color. Pick a hue that sits between your two endpoints on the shorter path around the wheel, and give it the same or higher saturation as your endpoints. A color picker that shows the HSL hue slider is useful here — just find the hue halfway between your two endpoint hues and crank the saturation.
You can also use more than one midpoint stop for a rainbow-like sweep. Three or four stops let you trace any arc around the color wheel you want, in full sRGB with no special syntax.
Fix 3: Switch the Interpolation Color Space
Modern CSS lets you declare which color space the browser should use when interpolating a gradient. Two spaces in particular keep chroma high throughout the blend:
- OKLCH — perceptual Lightness, Chroma, Hue. The hue axis maps closely to human vision. Interpolating in OKLCH walks along a hue arc, not a straight RGB line, so chroma stays high.
- HSL — Hue, Saturation, Lightness in the traditional cylindrical model. Better than sRGB for hue-arc blends, but HSL lightness is not perceptually uniform (some hues appear darker than others at the same HSL lightness value).
The syntax uses the in <color-space> keyword inside the gradient function:
/* Default sRGB — produces gray midpoint with complementary colors */
background: linear-gradient(135deg, blue, yellow);
/* OKLCH interpolation — vivid all the way through */
background: linear-gradient(in oklch, blue, yellow);
/* HSL interpolation — also avoids gray, less perceptually uniform */
background: linear-gradient(in hsl, blue, yellow);
/* Works with radial and conic gradients too */
background: radial-gradient(in oklch, #0057ff, #ff6b00);
background: conic-gradient(in oklch, #0057ff, #ff6b00); The in oklch version of a blue-to-yellow gradient passes through vivid greens and
cyans, because that is the shorter hue arc between those two colors in OKLCH space. The result
looks like a natural rainbow segment rather than a muddy blend.
Browser support: OKLCH gradient interpolation landed in Chrome 111, Firefox 113, and Safari 16.2 (all released in 2023). As of 2025, global coverage exceeds 90%. For the remaining users, a plain sRGB fallback works fine — place it before the OKLCH declaration so capable browsers override it:
/* Fallback for older browsers */
background: linear-gradient(135deg, #0057ff, #8800ff 50%, #ff6b00);
/* Modern browsers use this one */
background: linear-gradient(in oklch, #0057ff, #ff6b00); Fix 4: Steer the Hue Path With shorter hue / longer hue
When interpolating in a cylindrical color space (HSL, OKLCH, LCH), the browser must decide
which direction to go around the hue circle — shorter arc or longer arc. By default it picks
the shorter path. You can override this with the shorter hue or longer hue hue interpolation method:
/* Default: takes the shorter arc (may cross a low-saturation zone) */
background: linear-gradient(in oklch, #ff0000, #00ffff);
/* Longer arc: sweeps through the full warm palette instead */
background: linear-gradient(in oklch longer hue, #ff0000, #00ffff);
/* HSL shorter hue: takes the shortest hue path */
background: linear-gradient(in hsl shorter hue, hsl(30 100% 50%), hsl(270 100% 50%)); This technique is especially useful when you want a gradient that passes through warm reds and oranges rather than through cool greens, or vice versa. It is purely a creative choice — both paths avoid the sRGB gray dead-zone as long as you stay in a cylindrical color space.
Putting It Together: Before and After
Here is the same pair of colors — a vivid blue and a vivid orange — rendered three ways:
/* Before: two-stop sRGB — gray dead-zone at 50% */
background: linear-gradient(135deg, #0057ff, #ff6b00);
/* After option A: three-stop sRGB — midpoint color breaks the gray */
background: linear-gradient(135deg, #0057ff, #cc00ff 50%, #ff6b00);
/* After option B: OKLCH — no extra stops needed, vivid throughout */
background: linear-gradient(in oklch, #0057ff, #ff6b00); Option B (OKLCH) is the cleanest — one line, no hand-picked midpoint, and the result is perceptually smooth. Use the three-stop sRGB approach as a fallback or when you need precise control over which hue the midpoint passes through.
For a deeper look at gradient types — linear, radial, and conic — and when to use each, see the overview article on CSS linear, radial, and conic gradients.
The fastest way to experiment with all of these techniques is the CSS Gradient Generator — it lets you tweak stops, color spaces, and angles interactively and copies the final CSS with one click.
Frequently Asked Questions
Why does my gradient look gray in the middle?
The default CSS gradient engine interpolates in sRGB. When your endpoint colors sit on
opposite sides of the hue wheel (complementary colors), the midpoint in raw RGB space passes
through a region of very low chroma — which looks gray or brown. This is not a browser bug;
it is what sRGB interpolation produces for complementary color pairs. Fix it with analogous
colors, a vivid midpoint stop, or in oklch interpolation.
What is OKLCH interpolation?
OKLCH is a perceptual color space that models color as three independent axes: Lightness
(L), Chroma (C), and Hue (H). Unlike sRGB, its hue axis forms a continuous circle where
adjacent hue values look adjacent to human eyes. When you write linear-gradient(in oklch, blue, yellow), the browser walks along the OKLCH hue
arc between the two colors rather than mixing raw R, G, B channels. The arc stays in
high-chroma territory, so the gradient remains vivid from edge to edge. Browser support is
broad as of 2024-2025 (Chrome 111+, Firefox 113+, Safari 16.2+).
How many color stops should a gradient have?
Two stops are enough when the colors are analogous or when you use OKLCH/HSL interpolation.
For complementary pairs in sRGB, one extra stop at the midpoint — set to a vivid in-between
hue — eliminates the gray dead-zone. Three stops are sufficient for most designs. Use more
stops only when you need a deliberate multi-hue sweep (rainbow, sunset, aurora). More stops
also increase CSS verbosity, so prefer the in oklch syntax when browser support allows,
and reach for extra stops as a fallback.
