Understanding gradients
Two colours and a path between them.
Linear, radial, conic — and why the colour space you interpolate through changes everything in the middle.
Three gradient types.
CSS supports three gradient shapes. linear-gradient travels in a straight line at an angle. radial-gradient fans out from a centre — circular or elliptical, with stops measured from that centre. conic-gradient sweeps around a centre like the hands of a clock, useful for pie charts, colour wheels and progress rings. Each takes a list of colour stops; the engine fills the space between them.
linear · radial · conic
The "muddy middle" problem.
A gradient from blue to yellow in sRGB famously goes through a dirty grey in the middle, because the engine averages the red, green and blue channels separately and the in-between value collapses toward neutral. Designers worked around this for years by inserting a deliberate mid-stop, often a saturated green, to keep the path off the grey axis. It worked, but it felt like fighting the tool.
Modern colour-space interpolation.
CSS Color 4 added a syntax for picking the colour space the gradient interpolates through: linear-gradient(in oklch, blue, yellow). OKLCH is a perceptually uniform space — the path between two colours stays at consistent lightness and visits hues that look like a straight line to the eye. That same blue-to-yellow gradient in OKLCH passes through clean greens, no grey detour. Modern Chromium, Safari and Firefox all support it.
Stops control the rhythm.
A gradient with two colours and no positions blends evenly. Add positions — red 0%, red 30%, blue 70%, blue 100% — and you get hard bands instead of a smooth fade. Two stops at the same position makes a hard line. Stops at 50.0001% and 50.0001% would make a knife-edge transition. Designers use this for striped backgrounds, conic pie charts and the rainbow swatch you sometimes see on a settings screen.
Banding, and how to fix it.
A long gradient between similar dark colours often shows visible bands on 8-bit displays — the colour space simply doesn't have enough steps. Three escape hatches: pick stops that sit further apart in luminance, add a tiny SVG noise layer over the gradient (CSS filter: url(#noise) on a referenced filter does it), or output a 10-bit gradient via the display-p3 colour space if your audience is on modern hardware. Banding is almost always cured by one of those three.
Performance.
A CSS gradient is cheap. The engine paints it once at the right size and caches the result; even a screen-sized linear gradient is fast on modern GPUs. Conic gradients with many stops cost a little more, but still less than a comparable PNG. The exception is animating the stops themselves — every frame is a fresh raster — which is best done sparingly or replaced with a transformed gradient layer on top of a fixed background.
Read next