On this page
The two kinds of mud
Every muddy gradient is some mixture of two distinct failures. Darkening: the midpoint is dimmer than either endpoint — blend bright red and bright green and the middle is a dull olive that looks like someone turned the lights down. Desaturation: the midpoint loses its color entirely — blend blue toward yellow and the middle passes through lifeless gray. Different causes, different fixes, and a gradient can suffer both at once.
Cause one: averaging gamma-encoded numbers
Stored RGB values are gamma-encoded — related to physical light by a curve, not a straight line, as our RGB guide explains in depth. Naively averaging rgb(255,0,0) and rgb(0,255,0) gives rgb(128,128,0), and 128 is not half the light of 255 — it's roughly a fifth. The averaged midpoint therefore emits less total light than either endpoint: mathematically inevitable darkness, baked into any tool that interpolates raw channel values (which historically meant CSS gradients, canvas, and most image editors).
The fix is to do the math in a space that respects light or perception. Mixing in linear RGB fixes the physics; mixing in a perceptual space like OKLab fixes the physics and keeps the steps looking even. That's exactly why our color mixer blends through OKLab by default and shows the naive-RGB result alongside for comparison — the difference in the midpoints isn't subtle.
Cause two: the path runs through gray
Picture the color wheel. Blending two hues on opposite sides — blue and yellow, red and cyan — along a straight line means passing through the center, and the center is gray. That's the desaturation mud: not a math error, but a routing decision. Interpolating channel-by-channel takes the straight road, and the straight road goes through the least colorful point in the entire space.
The fix is to change the route. Interpolating in a hue-based space (HSL, or better, OKLCH) travels around the wheel instead of through it — blue to yellow via green, or via magenta-red, staying saturated the whole way. Which arc you take matters aesthetically (the two directions pass through very different territory), and near-complementary pairs are genuinely hard: any route makes a statement. The pragmatic alternative is to stop asking one blend to span the whole wheel — insert a deliberately chosen intermediate stop and blend two shorter, cleaner segments instead.
Practical fixes, in order of effort
- Add a middle stop. The lowest-tech fix: pick the midpoint yourself (a vivid color from the neighborhood you want the gradient to pass through) and add it as a stop in the gradient generator. One good manual stop overrides both kinds of mud at once.
- Choose closer hues. Analogous pairs — neighbors on the wheel — barely mud at all, which is why sunset-style gradients (red→orange→yellow) look effortless. The wider the hue gap, the more the routing problem bites; our harmony guide maps the neighborhoods.
- Blend in a better space. Where you control the interpolation — build the ramp's intermediate values in OKLab/OKLCH with the mixer and paste the resulting stops into your gradient as explicit colors. Modern CSS is also gaining native
in oklab/in oklchinterpolation syntax for gradients, with support still settling; explicit stops work everywhere today. - Fade to the right transparent. The "fade to nothing" gradient has its own historical gray-fringe bug — fading toward transparent black — covered with the fix in our alpha guide: fade to a zero-alpha version of the same color.
When mud is the point
A last honest note: passing through gray isn't always wrong. Muted, desaturated transitions are a legitimate aesthetic — fog, dusk, restraint — and the toned-down middle is sometimes exactly the mood a design needs (that's tones doing their job). The goal isn't to eliminate the gray path; it's to stop taking it by accident. Once you know where the mud comes from, every gradient becomes a choice instead of a surprise.