CSS Gradients Without the Muddy Grey Band in the Middle
3 min read3 October 2026By Muhammad Abdullah
You pick two vivid colours, put them in a gradient, and the middle comes out a dull, dusty grey. It is not your eyes and it is not a bug. It is how the browser blends colours by default, and once you know why it happens there are three clean ways to stop it.
Why the middle goes grey
By default a gradient blends in the sRGB colour space, which means it averages the red, green and blue channels separately. Take a bright blue and a bright orange. They sit on opposite sides of the colour wheel, so as one channel rises the others fall, and halfway along every channel lands near the middle. Middling values in all three channels is, almost by definition, grey.
/* blue to orange: the midpoint is a dusty mauve-grey */
background: linear-gradient(90deg, #2563eb, #f97316);The midpoint of those two works out to roughly rgb(143 107 128), a muted, desaturated colour that neither endpoint suggested. The further apart two colours are on the wheel, the worse the dip.
Fix one: add a stop in between
The oldest and most reliable fix is to tell the gradient which way to travel. Add a third colour that sits between the two on the wheel, and the blend runs through it instead of cutting through grey.
/* routed through pink, so the middle stays vivid */
background: linear-gradient(90deg, #2563eb, #db2777, #f97316);Fix two: choose colours that are closer
Colours that are neighbours on the wheel, blue to violet, or orange to pink, blend cleanly because their channels move together rather than against each other. If the design allows it, an analogous pair simply avoids the problem.
Fix three: interpolate in oklch
Modern CSS lets you choose the colour space the gradient blends in. In oklch, a gradient travels around the hue wheel at a consistent lightness and chroma instead of averaging channels, so two vivid colours stay vivid all the way across.
/* same two colours, blended in oklch: no grey */
background: linear-gradient(90deg in oklch, #2563eb, #f97316);This is supported in all current major browsers. For older ones, put a plain sRGB gradient on the line above as a fallback; a browser that does not understand the second declaration simply keeps the first.
Stop positions control where the blend happens
Two stops at 0 and 100 percent spread the transition across the whole element. Pull them inward and each colour holds flat at the ends while the blend concentrates in the middle. Put two stops at the same position and you get a hard line with no blend at all, which is how two-tone backgrounds and stripes are made.
/* a hard split: no transition between the two halves */
background: linear-gradient(90deg, #2563eb 50%, #f97316 50%);One more thing: gradients are images
A gradient is a generated image, not a colour, so it belongs in background-image or the background shorthand. Setting background-color to a gradient does nothing at all, and it is a surprisingly common reason a gradient fails to appear.
Common questions
Why does my gradient have a grey band in the middle?
Because sRGB blending averages each colour channel, and two colours from opposite sides of the wheel average out to grey. Add a middle stop or blend in oklch.
Is oklch gradient interpolation safe to use?
Yes, in all current major browsers. Add a plain gradient on the line before as a fallback for older ones.
How do I make a gradient with a hard edge?
Give two adjacent stops the same position. The colour changes instantly at that point instead of blending.