CSS Gradients: Linear, Radial, and Conic Explained

CSS gradients in one minute
A CSS gradient is a smooth transition between two or more colors that the browser paints as an image. Because gradients are images, you use them anywhere an image is valid: background, background-image, border-image, and mask. There are three gradient functions, and every one of them has a repeating twin:
.linear { background: linear-gradient(to right, #6a11cb, #2575fc); }
.radial { background: radial-gradient(circle, #6a11cb, #2575fc); }
.conic { background: conic-gradient(from 0deg, #6a11cb, #2575fc); }
That's the whole toolkit. linear-gradient() runs colors along a straight line, radial-gradient() spreads them out from a center point, and conic-gradient() sweeps them around a center like a color wheel. Everything else is just controlling the angle, the shape, and where each color stops.
Gradients are fully supported in every modern browser (Chrome, Edge, Firefox, Safari). No vendor prefixes are needed in 2026 unless you're targeting genuinely ancient browsers, and even then Autoprefixer handles it for you.
linear-gradient(): the workhorse
linear-gradient() takes a direction, then a list of colors:
.hero {
background: linear-gradient(to bottom right, #ff512f, #dd2476);
}
Setting the direction
You can express direction two ways, and they are not the same:
- Keywords —
to top,to right,to bottom left. These point at a side or corner and adapt to the box's aspect ratio. - Angles —
45deg,0.25turn,3.14rad.0degpoints straight up, and the angle increases clockwise, so90degpoints right and180degpoints down.
The gotcha: to right and 90deg look identical on a square, but on a wide rectangle a corner keyword like to top right aims at the actual corner while 45deg stays a fixed 45 degrees. When you want the gradient to hit the corners cleanly, use keywords.
/* Identical on a square, but diverge on a rectangle */
.keyword { background: linear-gradient(to top right, #000, #fff); }
.angle { background: linear-gradient(45deg, #000, #fff); }
Color stops and hard edges
Each color can carry a position, which tells the browser where that color should land along the line. Positions unlock two powerful tricks.
Solid stripes. Give two adjacent colors the same position and the transition collapses into a hard line:
.stripes {
background: linear-gradient(
to right,
#6a11cb 0% 50%,
#2575fc 50% 100%
);
}
That double-position syntax (#6a11cb 0% 50%) is a shorthand for repeating the color at two stops. It's the cleanest way to build flags, split backgrounds, and progress bars.
Transition hints. A lone percentage between two colors moves the midpoint of the blend without adding a color:
.eased {
background: linear-gradient(to right, #f00, 20%, #00f);
}
Here the perceptual halfway point sits at 20% instead of 50%, easing the fade.
radial-gradient(): circles and ellipses
radial-gradient() radiates color outward from a center. The syntax names a shape and size, an optional position, then the color stops:
.glow {
background: radial-gradient(
circle at center,
#ffd200,
#f7971e 70%
);
}
Shape, size, and position
- Shape is
circleorellipse(the default). An ellipse stretches to match the box. - Size can be a length, or a keyword:
closest-side,closest-corner,farthest-side, orfarthest-corner(the default). These describe how far the gradient reaches before the last color takes over. - Position uses
at <position>, accepting the same values asbackground-position—at center,at top left,at 30% 70%.
A common pattern is a soft spotlight that doesn't fill the whole box:
.spotlight {
background: radial-gradient(
circle 120px at 30% 40%,
rgba(255,255,255,0.9),
rgba(255,255,255,0) 100%
);
}
The explicit 120px radius plus a transparent final stop gives you a contained glow, handy for hover highlights and card lighting effects.
conic-gradient(): pie charts and color wheels
conic-gradient() sweeps colors around a center point rather than out from it. That single difference makes it the right tool for pie charts, loading spinners, and color pickers — things that were image-only for years.
.pie {
background: conic-gradient(
#e63946 0% 25%,
#f1faee 25% 50%,
#a8dadc 50% 75%,
#457b9d 75% 100%
);
border-radius: 50%;
}
Add border-radius: 50% and you have a real pie chart in four lines of CSS, no library, no SVG. You can also set a starting angle and center with from 90deg at 50% 50%.
A genuine color wheel is a one-liner because conic-gradient() accepts the hsl() hue sweep naturally:
.wheel {
background: conic-gradient(
hsl(0 100% 50%),
hsl(60 100% 50%),
hsl(120 100% 50%),
hsl(180 100% 50%),
hsl(240 100% 50%),
hsl(300 100% 50%),
hsl(360 100% 50%)
);
border-radius: 50%;
}
Which gradient should you use?
| Function | Colors travel | Best for | Default direction |
|---|---|---|---|
linear-gradient() |
Along a straight line | Backgrounds, buttons, overlays, stripes | Top to bottom |
radial-gradient() |
Outward from a point | Spotlights, glows, vignettes, orbs | Center, ellipse, farthest-corner |
conic-gradient() |
Around a center | Pie charts, spinners, color wheels | From 0deg (top), at center |
Stacking and repeating gradients
Layering multiple gradients
Because gradients are images, you can stack them in one background declaration, separated by commas. The first layer sits on top. Transparency lets lower layers show through:
.layered {
background:
linear-gradient(rgba(0,0,0,0.6), rgba(0,0,0,0.6)),
radial-gradient(circle at 20% 20%, #ff8a00, transparent 40%),
linear-gradient(120deg, #1a2980, #26d0ce);
}
That first semi-opaque black layer is the standard image-darkening overlay trick: drop it over a photo (url(...)) so white text stays readable regardless of the picture underneath.
Repeating gradients for patterns
repeating-linear-gradient() and repeating-radial-gradient() tile a stop pattern across the whole box, which is how you make stripes, grids, and graph paper without an image file:
.barber-pole {
background: repeating-linear-gradient(
45deg,
#ffcc00 0 20px,
#222 20px 40px
);
}
The pattern repeats every 40px forever. Swap in transparent colors and layer two repeating gradients at 90 degrees to each other and you get a grid.
Animating and theming gradients
You can't transition the color stops of a gradient directly — the browser has no way to interpolate between two linear-gradient() images. The reliable approaches:
- Animate
background-positionon an oversized gradient to create a moving-shimmer effect. - Animate a rotation with
@propertyfor the angle (modern browsers), or wrap the gradient element and rotate it. - Swap gradients on hover and let a color on a pseudo-element cross-fade.
For a smooth animated background, size the gradient larger than the box and slide it:
.animated {
background: linear-gradient(270deg, #ee7752, #e73c7e, #23a6d5);
background-size: 600% 600%;
animation: drift 12s ease infinite;
}
@keyframes drift {
0% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
100% { background-position: 0% 50%; }
}
That combination of background-size and animated background-position is the standard pattern — see our CSS animations tutorial for the keyframe and timing details.
Gradients pair perfectly with CSS custom properties. Store your stops in variables and you can retheme every gradient on the page — including for dark mode — from a single :root block:
:root {
--grad-start: #6a11cb;
--grad-end: #2575fc;
}
.card {
background: linear-gradient(135deg, var(--grad-start), var(--grad-end));
}
Accessibility and performance notes
Gradients are cheap to render and, unlike image files, add zero network requests — a real performance win. Two things to watch:
- Contrast. Text over a gradient must clear WCAG contrast (4.5:1 for body text) at the lightest point of the gradient, not the average. Test the worst-case corner.
- Banding. Long gradients between similar colors can show visible bands on 8-bit displays. Adding an intermediate stop or a subtle transition hint usually smooths it.
Remember gradients live in the background layer, so they sit behind content and respect the box model — a gradient fills the padding box by default and stops at the border unless you change background-clip. That interplay between backgrounds and box sizing trips up a lot of developers, so it's worth having the box model fresh in your mind before you build complex layered gradients.
Start with linear-gradient(), reach for radial-gradient() when color needs to radiate, and pull out conic-gradient() the moment you need something to sweep around a center. With color stops and layering, those three functions cover almost every gradient you'll ever ship.