TH The Sass Way
CSS Techniques

CSS Gradients: Linear, Radial, and Conic Explained

CSS Gradients: Linear, Radial, and Conic Explained
tldrA CSS gradient is a smooth blend between two or more colors that the browser paints as an image, usable anywhere an image is valid. There are three functions: linear-gradient() runs colors along a straight line, radial-gradient() spreads them outward from a center point, and conic-gradient() sweeps them around a center. Each has a repeating variant for patterns, and all are supported in every modern browser without prefixes.

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:

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

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:

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:

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.

FAQ

How do you make a gradient in CSS?

Set a gradient function as a background: background: linear-gradient(to right, #6a11cb, #2575fc);. The first argument is the direction (a keyword like 'to right' or an angle like 90deg), followed by two or more colors. Swap in radial-gradient() or conic-gradient() for other shapes. Because gradients are images, they also work in background-image, border-image, and mask.

What is the difference between linear, radial, and conic gradients?

In a linear-gradient() the colors travel along a straight line set by an angle or keyword. In a radial-gradient() they spread outward from a center point in a circle or ellipse, ideal for glows and spotlights. In a conic-gradient() they sweep around the center like a clock hand, which makes pie charts, spinners, and color wheels possible in pure CSS.

How do you set the direction of a linear gradient?

Use a keyword or an angle as the first argument. Keywords like 'to right' or 'to top left' point at a side or corner and adapt to the box shape. Angles like 45deg or 0.25turn are fixed: 0deg points up and the value increases clockwise, so 90deg points right and 180deg points down. On non-square boxes the two methods can differ.

Can you animate a CSS gradient?

You can't transition a gradient's color stops directly because the browser can't interpolate between two gradient images. Instead, make the gradient larger than the box with background-size and animate background-position for a drifting shimmer, or animate a rotation. Registering the angle as an @property in modern browsers lets you animate a conic sweep smoothly.

How do you create a color gradient overlay on an image?

Stack a semi-transparent gradient on top of the image in one background declaration, comma-separated: background: linear-gradient(rgba(0,0,0,0.6), rgba(0,0,0,0.6)), url(photo.jpg);. The first layer sits on top and darkens the photo evenly so overlaid text stays readable. Adjust the alpha value to control how much the image shows through.

Do CSS gradients need vendor prefixes?

Not in 2026. Linear, radial, and conic gradients are supported unprefixed in every current version of Chrome, Edge, Firefox, and Safari. You only need old -webkit- or -moz- prefixes for very outdated browsers, and a build tool like Autoprefixer adds those automatically based on your browserslist targets, so you never write them by hand.