Pure flat fills are easy. The gradients in real dark UIs are less so — get them wrong and they band, run the wrong direction, or fight the foreground. This page is a short field reference: enough syntax to write the gradient you want, plus the corner cases that actually come up.
The two functions you need
CSS has several gradient functions. For dark backgrounds, two of them do almost all the work:
linear-gradient()— colour transitions along a line. Used for top-to-bottom fades, oblique header strips and subtle horizon effects.radial-gradient()— colour transitions along a circle or ellipse. Used for spotlights, vignettes, and "centre lights up" hero blocks.
conic-gradient() exists, and repeating-linear-gradient() is useful for stripes, but on black backgrounds you rarely reach for either; the first reads as a colour wheel, the second as graphic stripes.
Linear: angle, stops, and the "where does it start"
The first argument is direction. Two equivalent ways to write the same fade:
/* keyword direction — readable, prefer this */
.bg-fade {
background: linear-gradient(to bottom, #000, #1a1a1a);
}
/* angle direction — 180deg also points down */
.bg-fade {
background: linear-gradient(180deg, #000, #1a1a1a);
}
CSS angles in linear-gradient use a clockwise convention starting from "up": 0deg is up, 90deg right, 180deg down, 270deg left. This is the opposite of mathematical convention and the source of most "why is my gradient sideways?" bugs.
Stops let you control where colours land along the line:
.bg-fade {
background: linear-gradient(180deg,
#000 0%,
#000 40%,
#1a1a1a 100%);
}
Repeating a colour at two stops creates a flat region — the example above is "pure black for the top 40%, then fade". Use this to push the gradient out of the area where headlines sit, so they read against a flat field.
Radial: ellipse vs circle, position, sizing
Radial gradients are the workhorse for "spotlight" looks on dark heroes:
.bg-spotlight {
background:
radial-gradient(ellipse at center,
#2a2a2a 0%,
#000 70%);
}
Three things to know:
- Shape.
ellipsestretches with the box;circlestays round. For full-bleed page heroes,ellipselooks more cinematic; for square cards,circlereads better. - Position.
at center,at 30% 20%, or named positions likeat top right. Off-centre radial gradients put a "light source" in the corner — useful for product hero shots. - Size keyword.
closest-side,farthest-corner(the default),closest-corner,farthest-sidecontrol how far the gradient reaches before its last stop.farthest-corneris what you want for full-page vignettes.
Easing approximation: avoiding banded transitions
CSS gradients interpolate linearly between stops. The eye does not see brightness linearly, so a gradient between two near-black colours looks "stepped" or banded in the middle range. There are two practical fixes.
Multi-stop approximation
Insert intermediate stops so the perceived curve is closer to ease-out:
.bg-smoother {
background: linear-gradient(180deg,
#000 0%,
#050505 25%,
#0a0a0a 50%,
#121212 75%,
#1a1a1a 100%);
}
Five stops is usually enough. Going beyond ten is wasted effort.
Native interpolation hints
Modern browsers support an interpolation hint — a single percentage between two stops that biases the curve:
.bg-eased {
background: linear-gradient(180deg,
#000 0%,
65%, /* push the midpoint toward the dark end */
#1a1a1a 100%);
}
Combine this with the grain technique to fully eliminate visible bands on cheap displays.
Layering: gradient + pattern + colour
CSS lets you stack multiple backgrounds in one declaration. The first one listed paints on top:
.hero {
background:
radial-gradient(ellipse at center,
rgba(255,255,255,0.05) 0%,
transparent 60%),
linear-gradient(180deg, #000, #0a0a0a);
}
This is a near-black page with a faint centre highlight. The first gradient uses an alpha channel so it can lift the colour underneath rather than replacing it.
The same trick is what powers the generator's pattern overlays: a vector or canvas-rendered pattern sits on top of a flat or gradient base. If you are exporting CSS straight from the generator, the layered background declaration that comes out is exactly this shape — a pattern layer over a base colour.
Blend modes
Two properties matter:
background-blend-mode— blends multiple background layers into each other.mix-blend-mode— blends the entire element into what is behind it.
For dark backgrounds, the useful blend modes are screen (lifts dark values, useful for adding glow), overlay (preserves blacks while increasing midtone contrast) and soft-light (gentle texture without changing the overall tone). Avoid multiply — it crushes near-black to pure black and amplifies banding.
Performance and paint cost
Gradient backgrounds are nearly free at paint time on every modern browser. The performance trap is animating a gradient by changing one of its stop colours — that triggers a full repaint of the painted area on every frame. If you need a moving gradient effect, animate background-position on a larger-than-viewport gradient, or use a CSS custom property and let the browser interpolate it.
Fallbacks worth keeping
Browsers without gradient support are essentially extinct as of the mid-2020s, but the one fallback worth keeping is a solid background-color sitting underneath the background shorthand:
.hero {
background-color: #0a0a0a; /* fallback */
background: /* layered, gradients */
radial-gradient(ellipse at center,
rgba(255,255,255,0.05) 0%,
transparent 60%),
linear-gradient(180deg, #000, #0a0a0a);
}
If the rendering engine fails any single layer, the box still has a sensible dark colour. This is also the right pattern for emails and printable PDFs, where gradient support is unreliable.
Common mistakes
- Gradient in the wrong direction. Remember
0degis up, not right. - Two near-identical near-blacks. A gradient between
#000and#020202is invisible; you wrote a flat fill with extra steps. - Using
multiplyblend mode for "depth". It crushes the gradient and amplifies banding. Useoverlayorsoft-light. - Layering pure-black gradient stops where you wanted near-black. See pure vs near-black — for body text surfaces, end the gradient at
#0a0a0arather than#000. - Animating gradient stops directly. Animate
background-positionon an oversized gradient instead.
What to do next
Open the generator, switch the background type to "Linear" or "Radial", and use the matrix view to compare gradients quickly. Copy the CSS from any tile via the "Show CSS" button. If the result bands on your monitor, see grain and banding; if you are pairing the gradient with a pattern, the pattern guide covers density. For body-text surfaces, finish the gradient at the values from pure vs near-black.
Last reviewed on 28 April 2026.
← Back to generator