A flat two-colour gradient looks fine. A wow gradient, the kind that makes a hero section feel expensive, follows a handful of rules most people never learn. This guide walks through all of them, with side-by-side swatches, copy-paste CSS, and the specific mistakes that make a fade look muddy. By the end you’ll be able to look at any gradient and say exactly why it works or doesn’t.
First, the anatomy
Every CSS gradient is three decisions: a type (linear, radial, or conic), a direction (an angle or a centre point), and a list of colour stops. A stop is a colour plus an optional position. The browser draws a straight path in colour space between each pair of adjacent stops.
/* type direction stop 1 stop 2 */
background: linear-gradient(135deg, #7C5CFF 0%, #FF9E6D 100%);That one line contains everything that can go right or wrong. The rest of this guide is really about choosing those stops and that angle well, because the defaults almost always produce the dull version.
1. Use three or more stops, not two
Two colours give you a straight line through colour space. Adding a middle stop lets the gradient curve, passing through a hue it wouldn’t otherwise reach. That extra hue is where the richness comes from.
2 stops: muddy middle
3 stops: glowing middle
Why does the two-stop version go grey in the middle? Because purple and coral sit on opposite sides of the hue wheel. The straight line between them in sRGB passes close to the low-saturation centre, so the midpoint desaturates. A third stop pins the path to a colour you actually want, so the gradient never dips into mud.
/* Flat: the midpoint desaturates on its own */
background: linear-gradient(90deg, #7C5CFF, #FF9E6D);
/* Rich: a pink waypoint keeps saturation high the whole way */
background: linear-gradient(90deg, #7C5CFF, #FF5E9A 50%, #FF9E6D);Three to five stops is the sweet spot. Past five or six you’re usually adding stops that are visually indistinguishable, which is effort with no payoff.
2. Keep the hues analogous (or make one jump on purpose)
Colours next to each other on the wheel, like purple, magenta, pink and coral, blend without turning grey. When two stops sit far apart (say blue and orange), the gradient passes through a dead, desaturated middle. There are two ways to handle a wide hue gap:
- Stay analogous. Keep every stop within roughly 90° of hue of its neighbours. The transition stays saturated automatically.
- Jump on purpose. If you want a bold blue→orange move, drop a saturated waypoint right at the midpoint (a magenta or teal) so the eye never sees the grey zone.
A quick tell: if your gradient looks great at the ends but washed out in the centre, your hues are too far apart. Add a waypoint or pull the endpoints closer on the wheel.
3. Mind the angle
A diagonal (135°) reads as more dynamic than a flat left-to-right, and it plays better with rectangular sections because the eye travels corner to corner. Small change, big difference in energy.
Flat, left to right
Diagonal at 135°
Don’t stop at linear. Two other types earn their keep:
- Radial gradients read as a glow or a spotlight, which is perfect for a soft highlight behind a headline:
radial-gradient(circle at 30% 20%, #7C5CFF, transparent 60%). - Conic gradients sweep around a point and are how you build colour wheels, pie charts, and the “angular” hero backgrounds that feel current:
conic-gradient(from 210deg, #7C5CFF, #FF5E9A, #FF9E6D, #7C5CFF).
Layer them. A base linear gradient with a low-opacity radial glow stacked on top (using multiple comma-separated backgrounds) is the single fastest way to make a section look designed rather than filled.
Radial: a soft glow
Conic: sweeps around
4. Watch for banding
On large areas, gradients can show visible steps (“banding”), especially in dark UIs where each 8-bit step is more noticeable. Here are three fixes, starting with the cheapest:
- Add a stop. More stops means shorter transitions, and shorter transitions band less.
- Overlay noise. A barely-there noise texture at 1–2% opacity breaks the bands up. You can do it with a tiny tiled PNG or an inline SVG
feTurbulencefilter, so there’s no image request. - Interpolate in a better space. Modern CSS lets you say
in oklch, which spreads the steps more evenly and bands far less (more on that below).
/* Noise overlay via a stacked background */
background:
linear-gradient(135deg, #7C5CFF, #FF5E9A 50%, #FF9E6D),
url("data:image/svg+xml,..."); /* 2% opacity turbulence */
background-blend-mode: overlay;5. Interpolate in OKLCH, not sRGB
Here’s the upgrade almost nobody uses. By default the browser mixes gradients in sRGB, the space that causes the grey-middle problem in the first place. Tell it to mix in a perceptual space instead and the same two colours produce a smoother, brighter blend with no extra stops:
/* Same endpoints, better interpolation */
background: linear-gradient(in oklch, #7C5CFF, #FF9E6D);OKLCH keeps perceived lightness even across the transition, so the midpoint doesn’t dip. It’s supported in every current browser. If you only change one thing after reading this, make it this line.
sRGB greys out
OKLCH stays bright
6. Pull colours from something real
The best gradients are usually sampled from something real. A sunset photo, a product shot, a piece of album art already contains a set of hues that belong together because they came from the same light. Eyedrop three or four and you have a palette that feels natural instead of arbitrary. This is why “designed” gradients so often beat ones assembled from a colour picker: the source did the harmony work for you.
Copy-paste recipes
Three gradients you can drop in today and tweak:
/* 1. Expensive hero */
background: linear-gradient(in oklch 135deg,
#7C5CFF, #C264FF 40%, #FF5E9A 70%, #FF9E6D);
/* 2. Soft glow behind a headline */
background: radial-gradient(circle at 30% 20%,
rgba(124,92,255,.45), transparent 60%);
/* 3. Subtle dark-UI panel sheen */
background: linear-gradient(160deg, #12101f, #0b0916);Common mistakes
- Two far-apart stops and nothing between them. The number-one cause of muddy gradients. Add a waypoint or switch to
in oklch. - Pure black or pure white as a stop. They flatten everything they touch. Use a very dark tinted colour (
#0b0916) or a near-white instead. - Too many stops. Six evenly-spaced stops rarely look better than three well-chosen ones, and they take longer to tune.
- Ignoring banding on big backgrounds. It looks fine in your 400px preview and posterises across a 2560px hero. Test at full width.
- Text over a gradient without checking contrast. The ratio shifts across the blend, so check that the lightest and darkest points pass WCAG.
Studio Colour’s gradient extractor pulls a full multi-stop gradient off any element on any page. It reads and writes OKLCH so your blends stay smooth, and eyedrops real colours from images so your palette always belongs together. It’s a free Chrome side panel.


