Three functions, three different paths
A gradient is a blend along a path, and the three functions differ in what that path is.
- Linear runs along a straight line at an angle you set.
0deg points up and angles increase clockwise, so 90deg runs left to right and 180deg top to bottom.
- Radial spreads outward from a point. An angle means nothing to it; a centre position does.
- Conic sweeps around a point like a clock hand. This is the one used for pie charts, colour wheels and progress rings, and it is rarely the right choice for a page background.
The [msm_tool slug="gradient-builder"] swaps the angle control for a centre position when you choose radial, because carrying an angle across would be offering a setting that does nothing.
Why gradients go grey in the middle
The single most common complaint, and it is not a bug.
Interpolation runs through the colour space between your two stops. Colours on opposite sides of the wheel — a blue and an orange, a red and a green — meet at a desaturated point on the way, and that point is grey or a muddy brown.
The fix is a third stop that steers the blend around rather than through the middle. Going from blue to orange, add a stop of a saturated violet or teal depending on which way round you want the transition to travel. Two stops give you no control over the path; three do.
Stop positions
Each stop carries a position as a percentage along the path, and the colour is pure at that position. The blend happens between them.
That means two stops at 40% and 60% give a solid band at each end and a transition confined to the middle fifth. It also means the stops must be in ascending order — an out-of-order stop is legal CSS but renders as a hard band rather than a blend, which reads as a bug rather than a choice. The builder sorts them before writing the value for that reason.
Hard stops make stripes
Put two stops at the same position and the colour changes with no transition at all. That is how every CSS stripe, check and split-background is built, and it is worth knowing because it turns the gradient functions into a general-purpose shape tool rather than only a blending one.
linear-gradient(90deg, #fff 0%, #fff 50%, #eee 50%, #eee 100%) is a two-colour split down the middle, and no image was involved.
A gradient is an image
This catches people out in a specific place. Gradients belong in background or background-image, and they will not work anywhere a plain colour is expected.
border-color: linear-gradient(...) does nothing. For a gradient border, either use border-image, or put the gradient on a wrapper and inset the content with padding. For gradient text, the usual technique is a background gradient with background-clip: text and transparent text colour — which needs a solid fallback colour, since a browser that ignores the clip shows invisible text.
Banding
A slow transition across a large area steps visibly on 8-bit displays, showing as faint bands rather than a smooth blend. It is most obvious on subtle gradients between similar dark colours, which is exactly where designers reach for them.
Three things reduce it: more contrast between the stops, a smaller area, or a very faint noise overlay on top. The noise trick works because the dithering breaks up the flat bands, and it is what most large hero gradients quietly use.
Performance and accessibility
Gradients are cheap to paint and cost nothing worth measuring as static backgrounds. Animating one is different: gradients are not interpolatable properties, so transitioning between two of them does not blend — it snaps. The usual approach is to stack two gradients and transition the opacity of the top one.
On accessibility: text over a gradient has no single background colour to test. Sample the lightest and darkest points the text actually crosses and make sure the worst of them meets the contrast minimum. A gradient that passes at one end and fails at the other is a gradient with unreadable text on part of it.