What are CSS gradients

A CSS gradient is an image generated by the browser. That means gradients work anywhere an image is allowed, like background-image, mask-image, or even as one layer in a multi-background stack.

Also important: gradients are not colors. You can’t do color: linear-gradient(...). But you can use gradients as backgrounds, and then do cool things like “gradient text” by clipping the background to the text.

  • Use gradients when you want smooth transitions between colors without loading image files.
  • Gradients scale perfectly (no blurriness from upscaling).
  • Gradients can be layered, repeated, and animated.
.demo {
  background-image: linear-gradient(90deg, #7c3aed, #22c55e);
}
  
.demo {
  background-image: radial-gradient(circle, #f97316, #0ea5e9);
}
  
.demo {
  background-image: conic-gradient(from 0deg, #ef4444, #f59e0b, #22c55e, #3b82f6, #ef4444);
}
  
*,
::before,
::after {
  box-sizing: border-box;
}

.demo {
  width: min(560px, 92vw);
  height: 240px;
  border: 3px solid #111;
  border-radius: 18px;
  display: grid;
  place-items: center;
  font-family: ui-monospace, SFMono-Regular, Menlo;
  font-size: 18px;
  letter-spacing: 0.4px;
  color: #111;
  background-color: #fff;
}

.demo span {
  background: rgba(255, 255, 255, 0.75);
  padding: 10px 14px;
  border-radius: 999px;
  border: 2px solid rgba(17, 17, 17, 0.2);
}
  
Gradients are images (generated by CSS)

CSS linear-gradient

linear-gradient() creates a color transition along a straight line. You can control the direction (angle or keywords) and define multiple color stops.

Linear gradient basic syntax

The basic idea is: linear-gradient(direction, color-stop, color-stop, ...). The “direction” is optional—if you omit it, the gradient goes from top to bottom.

.demo {
  background-image: linear-gradient(#a855f7, #22c55e);
}
  
.demo {
  background-image: linear-gradient(to right, #a855f7, #22c55e);
}
  
.demo {
  background-image: linear-gradient(135deg, #a855f7, #22c55e);
}
  
.demo {
  background-image: linear-gradient(to top left, #a855f7, #22c55e);
}
  
*,
::before,
::after {
  box-sizing: border-box;
}

.demo {
  width: min(560px, 92vw);
  height: 240px;
  border: 3px solid #111;
  border-radius: 18px;
}

.hint {
  margin-top: 12px;
  font-family: ui-monospace, SFMono-Regular, Menlo;
  font-size: 14px;
  opacity: 0.85;
}
  

Try each snippet: default (top→bottom), to right, 135deg, to top left.

Color stops and positions

A “stop” is a color, optionally followed by a position like 30% or 120px. Positions help you control where each color lands.

  • Without positions, the browser spreads stops evenly.
  • With positions, you can make sharp transitions (great for stripes).
.demo {
  background-image: linear-gradient(to right, #0ea5e9 0%, #a855f7 50%, #f97316 100%);
}
  
.demo {
  background-image: linear-gradient(to right, #0ea5e9 0%, #0ea5e9 50%, #a855f7 50%, #a855f7 100%);
}
  
.demo {
  background-image: linear-gradient(
    90deg,
    #111 0%,
    #111 14%,
    #fbbf24 14%,
    #fbbf24 28%,
    #22c55e 28%,
    #22c55e 42%,
    #3b82f6 42%,
    #3b82f6 56%,
    #a855f7 56%,
    #a855f7 70%,
    #f97316 70%,
    #f97316 84%,
    #ef4444 84%,
    #ef4444 100%
  );
}
  
*,
::before,
::after {
  box-sizing: border-box;
}

.demo {
  width: min(560px, 92vw);
  height: 240px;
  border: 3px solid #111;
  border-radius: 18px;
}

.hint {
  margin-top: 12px;
  font-family: ui-monospace, SFMono-Regular, Menlo;
  font-size: 14px;
  opacity: 0.85;
}
  

Snippet 1: smooth stops. Snippet 2: hard edge at 50%. Snippet 3: multi-stop stripes.

Learn more about linear-gradient in the CSS Linear Gradient Interactive Tutorial.

CSS radial gradient

radial-gradient() radiates from a center point outward. It’s perfect for “spotlight” effects, soft blobs, and subtle depth.

Shape and position

You can choose circle or ellipse, and you can place the gradient using at x y.

.demo {
  background-image: radial-gradient(circle, #f97316, #0ea5e9 70%);
}
  
.demo {
  background-image: radial-gradient(ellipse at top left, #f97316, #0ea5e9 70%);
}
  
.demo {
  background-image: radial-gradient(circle at 70% 35%, #22c55e, #111 65%);
}
  
.demo {
  background-image: radial-gradient(closest-side at 30% 40%, #a855f7, #111);
}
  
*,
::before,
::after {
  box-sizing: border-box;
}

.demo {
  width: min(560px, 92vw);
  height: 260px;
  border: 3px solid #111;
  border-radius: 18px;
  background-color: #111;
}

.hint {
  margin-top: 12px;
  font-family: ui-monospace, SFMono-Regular, Menlo;
  font-size: 14px;
  opacity: 0.85;
}
  

Try moving the center with “at 70% 35%” and compare closest-side vs default sizing.

Radial gradient size keywords

Radial gradients have a size. You can use keywords to describe how far they reach: closest-side, farthest-side, closest-corner, farthest-corner.

  • closest-side reaches the nearest side of the box.
  • farthest-corner reaches the farthest corner (often looks “big” and soft).
.demo {
  background-image: radial-gradient(closest-side at 30% 40%, #38bdf8, #111);
}
  
.demo {
  background-image: radial-gradient(farthest-side at 30% 40%, #38bdf8, #111);
}
  
.demo {
  background-image: radial-gradient(closest-corner at 30% 40%, #38bdf8, #111);
}
  
.demo {
  background-image: radial-gradient(farthest-corner at 30% 40%, #38bdf8, #111);
}
  
*,
::before,
::after {
  box-sizing: border-box;
}

.demo {
  width: min(560px, 92vw);
  height: 260px;
  border: 3px solid #111;
  border-radius: 18px;
  background-color: #111;
}
  

Learn more about radial-gradient in the CSS Radial Gradient Interactive Tutorial.

CSS conic-gradient

conic-gradient() spins colors around a center point, like a color wheel or pie chart. It’s great for rings, angle-based color transitions, and “spinner” visuals.

Conic gradient basic syntax

Think of it as: colors progress around a circle. You can set a start angle with from, and move the center with at.

.demo {
  background-image: conic-gradient(#ef4444, #f59e0b, #22c55e, #3b82f6, #ef4444);
}
  
.demo {
  background-image: conic-gradient(from 90deg, #ef4444, #f59e0b, #22c55e, #3b82f6, #ef4444);
}
  
.demo {
  background-image: conic-gradient(at 30% 40%, #ef4444, #f59e0b, #22c55e, #3b82f6, #ef4444);
}
  
.demo {
  background-image: conic-gradient(
    from 180deg at 50% 50%,
    #111 0deg 40deg,
    #f97316 40deg 80deg,
    #111 80deg 120deg,
    #0ea5e9 120deg 160deg,
    #111 160deg 200deg,
    #a855f7 200deg 240deg,
    #111 240deg 280deg,
    #22c55e 280deg 320deg,
    #111 320deg 360deg
  );
}
  
*,
::before,
::after {
  box-sizing: border-box;
}

.demo {
  width: min(380px, 80vw);
  aspect-ratio: 1 / 1;
  border: 3px solid #111;
  border-radius: 18px;
  background-color: #fff;
  margin-inline: auto;
}
  

Making a ring (donut gradient)

A fun trick: layer a radial gradient on top of a conic gradient. The radial gradient “cuts out” the center so it becomes a ring.

.ring {
  background-image:
    radial-gradient(circle, #fff 0 56%, transparent 57%),
    conic-gradient(#22c55e, #3b82f6, #a855f7, #f97316, #22c55e);
}
  
.ring {
  background-image:
    radial-gradient(circle, #fff 0 65%, transparent 66%),
    conic-gradient(from 120deg, #ef4444 0 25%, #f59e0b 25% 50%, #22c55e 50% 75%, #3b82f6 75% 100%);
}
  
.ring {
  background-image:
    radial-gradient(circle, #fff 0 60%, transparent 61%),
    conic-gradient(from 180deg, #111 0 5%, #38bdf8 5% 30%, #111 30% 35%, #a855f7 35% 60%, #111 60% 65%, #22c55e 65% 95%, #111 95% 100%);
}
  
*,
::before,
::after {
  box-sizing: border-box;
}

.wrap {
  width: min(560px, 92vw);
  margin-inline: auto;
  display: grid;
  gap: 14px;
  justify-items: center;
}

.ring {
  width: 260px;
  aspect-ratio: 1 / 1;
  border: 3px solid #111;
  border-radius: 999px;
  background-color: #fff;
}
  

Repeating gradients

If you want patterns, meet: repeating-linear-gradient(), repeating-radial-gradient(), and repeating-conic-gradient().

The repeating versions repeat the gradient forever after the last stop. The “secret sauce” is making the stops end at a specific length (like 20px), so the pattern has a clear rhythm.

.demo {
  background-image: repeating-linear-gradient(
    45deg,
    #111 0 12px,
    #fbbf24 12px 24px
  );
}
  
.demo {
  background-image: repeating-linear-gradient(
    90deg,
    #0ea5e9 0 16px,
    #0ea5e9 16px 18px,
    #fff 18px 34px
  );
}
  
.demo {
  background-image: repeating-radial-gradient(
    circle at 40% 40%,
    #a855f7 0 10px,
    #111 10px 20px
  );
}
  
.demo {
  background-image: repeating-conic-gradient(
    from 0deg,
    #22c55e 0 12deg,
    #111 12deg 18deg
  );
}
  
*,
::before,
::after {
  box-sizing: border-box;
}

.demo {
  width: min(560px, 92vw);
  height: 260px;
  border: 3px solid #111;
  border-radius: 18px;
}
  

Layering multiple gradients

You can stack multiple background images by separating them with commas. The first one is drawn on top, the last one is at the back.

This is how you create “glows”, highlights, and more complex artwork without a single image file.

.card {
  background-image:
    radial-gradient(circle at 20% 20%, rgba(34, 197, 94, 0.55), transparent 55%),
    radial-gradient(circle at 80% 30%, rgba(59, 130, 246, 0.55), transparent 55%),
    linear-gradient(135deg, #ffffff, #f3f4f6);
}
  
.card {
  background-image:
    linear-gradient(135deg, rgba(168, 85, 247, 0.7), rgba(14, 165, 233, 0.2)),
    repeating-linear-gradient(90deg, rgba(17, 17, 17, 0.08) 0 1px, transparent 1px 12px);
}
  
.card {
  background-image:
    radial-gradient(circle at 50% 0%, rgba(249, 115, 22, 0.55), transparent 60%),
    radial-gradient(circle at 0% 100%, rgba(239, 68, 68, 0.45), transparent 60%),
    radial-gradient(circle at 100% 100%, rgba(34, 197, 94, 0.45), transparent 60%),
    linear-gradient(180deg, #ffffff, #f8fafc);
}
  
*,
::before,
::after {
  box-sizing: border-box;
}

.wrap {
  width: min(560px, 92vw);
  margin-inline: auto;
  display: grid;
  gap: 14px;
}

.card {
  border: 3px solid #111;
  border-radius: 18px;
  padding: 18px;
  font-family: ui-monospace, SFMono-Regular, Menlo;
  min-height: 220px;
  display: grid;
  align-content: start;
  gap: 10px;
}

.card p {
  margin: 0;
  opacity: 0.9;
}
  

Layered backgrounds feel fancy.

But it’s just commas and gradients.

Gradient borders with background-clip

CSS doesn’t have a direct border-image experience that feels nice to use every day, so a common trick is: use multiple backgrounds and clip them.

  • One gradient is the “border layer” (painted behind).
  • Another background is the “card layer” (painted on top, clipped to padding box).
.card {
  border: 10px solid transparent;
  background-image:
    linear-gradient(#ffffff, #ffffff),
    linear-gradient(135deg, #22c55e, #3b82f6, #a855f7, #f97316);
  background-clip: padding-box, border-box;
}
  
.card {
  border: 12px solid transparent;
  background-image:
    linear-gradient(#ffffff, #ffffff),
    conic-gradient(from 180deg, #ef4444, #f59e0b, #22c55e, #3b82f6, #ef4444);
  background-clip: padding-box, border-box;
}
  
.card {
  border: 10px solid transparent;
  background-image:
    linear-gradient(#ffffff, #ffffff),
    repeating-linear-gradient(90deg, #111 0 10px, #fbbf24 10px 20px);
  background-clip: padding-box, border-box;
}
  
*,
::before,
::after {
  box-sizing: border-box;
}

.card {
  width: min(560px, 92vw);
  margin-inline: auto;
  border-radius: 18px;
  padding: 18px;
  font-family: ui-monospace, SFMono-Regular, Menlo;
  min-height: 220px;
  display: grid;
  gap: 10px;
  align-content: start;
  color: #111;
}

.card p {
  margin: 0;
}

.card strong {
  font-weight: 800;
}
  

Gradient border with a real white interior.

The white layer is on top and clipped to the padding-box.

The gradient layer sits behind it and fills the border-box.

Text gradient CSS

Gradient text is a classic because it looks like wizardry, but the trick is simple: put the gradient on the background, then clip the background to the text.

  • You need background-clip: text (and the WebKit version for best support).
  • You also need the text fill to be transparent so the background shows through.
.title {
  background-image: linear-gradient(90deg, #22c55e, #3b82f6, #a855f7, #f97316);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
  
.title {
  background-image: radial-gradient(circle at 20% 30%, #f97316, #a855f7 55%, #3b82f6);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
  
.title {
  background-image: conic-gradient(from 180deg, #ef4444, #f59e0b, #22c55e, #3b82f6, #ef4444);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
  
*,
::before,
::after {
  box-sizing: border-box;
}

.wrap {
  width: min(540px, 92vw);
  margin-inline: auto;
  border: 3px solid #111;
  border-radius: 18px;
  padding: 18px;
  background: #fff;
}

.title {
  font-family: ui-monospace, SFMono-Regular, Menlo;
  font-size: clamp(28px, 4vw, 52px);
  font-weight: 800;
  letter-spacing: 0.6px;
  margin: 0;
  line-height: 1.05;
}

.sub {
  margin: 10px 0 0;
  font-family: ui-monospace, SFMono-Regular, Menlo;
  opacity: 0.85;
}
  

Gradient text: now you’re a wizard

It’s just background + clip + transparent text.

Text gradients on multi-line text

If your headline wraps onto multiple lines, the gradient is still one big background. That usually looks good, but it means line 2 is “continuing” the gradient from line 1.

If you want each line to have its own gradient block, you can experiment with box-decoration-break: clone when the text is inside an inline element.

.title {
  display: inline;
  background-image: linear-gradient(90deg, #22c55e, #3b82f6, #a855f7);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
}
  
.title {
  display: inline;
  background-image: linear-gradient(135deg, #f97316, #ef4444, #a855f7);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
  
*,
::before,
::after {
  box-sizing: border-box;
}

.wrap {
  width: min(540px, 92vw);
  margin-inline: auto;
  border: 3px solid #111;
  border-radius: 18px;
  padding: 18px;
  background: #fff;
  font-family: ui-monospace, SFMono-Regular, Menlo;
}

h2 {
  margin: 0;
  font-size: clamp(26px, 4vw, 46px);
  line-height: 1.1;
}

.note {
  margin: 12px 0 0;
  opacity: 0.85;
  font-size: 14px;
}
  

This title is long enough to wrap onto another line

Snippet 1 uses box-decoration-break. Snippet 2 is the default behavior.

CSS gradient animation

Animating gradients can be done in a few ways. Two common beginner-friendly approaches are:

  • Animate background-position while using a large background-size. This feels like the gradient is “moving”.
  • Animate a conic-gradient by rotating the element (simple and very effective).

Animated linear gradient by moving background-position

The trick: create a gradient that’s wider than the element, then slide it back and forth with background-position.

.banner {
  background-image: linear-gradient(
    90deg,
    #22c55e,
    #3b82f6,
    #a855f7,
    #f97316,
    #22c55e
  );
  background-size: 300% 300%;
  animation: gradient-move 6s ease-in-out infinite;
}

@keyframes gradient-move {
0% {
background-position: 0% 50%;
}

50% {
background-position: 100% 50%;
}

100% {
background-position: 0% 50%;
}
} 
*,
::before,
::after {
  box-sizing: border-box;
}

.banner {
  width: min(760px, 92vw);
  margin-inline: auto;
  border: 3px solid #111;
  border-radius: 18px;
  padding: 22px;
  min-height: 220px;
  display: grid;
  align-content: center;
  gap: 10px;
  font-family: ui-monospace, SFMono-Regular, Menlo;
}

.banner h3 {
  margin: 0;
  font-size: 26px;
  line-height: 1.1;
}

.banner p {
  margin: 0;
  opacity: 0.9;
  max-width: 52ch;
}

.badge {
  display: inline-block;
  background: rgba(255, 255, 255, 0.75);
  border: 2px solid rgba(17, 17, 17, 0.2);
  padding: 8px 12px;
  border-radius: 999px;
  width: fit-content;
}
  

  

Animated conic gradient spinner

Conic gradients plus rotation is a great combo. Instead of animating the gradient itself, you rotate the element. It’s smooth, cheap, and looks impressive.

.spinner {
  background-image: conic-gradient(
    from 0deg,
    rgba(17, 17, 17, 0) 0deg 40deg,
    #3b82f6 40deg 120deg,
    #a855f7 120deg 200deg,
    #f97316 200deg 280deg,
    rgba(17, 17, 17, 0) 280deg 360deg
  );
  animation: spin 1.1s linear infinite;
}

@keyframes spin {
to {
transform: rotate(360deg);
}
} 
*,
::before,
::after {
  box-sizing: border-box;
}

.wrap {
  width: min(560px, 92vw);
  margin-inline: auto;
  border: 3px solid #111;
  border-radius: 18px;
  padding: 22px;
  display: grid;
  place-items: center;
  gap: 14px;
  font-family: ui-monospace, SFMono-Regular, Menlo;
  background: #fff;
}

.spinner {
  width: 140px;
  aspect-ratio: 1 / 1;
  border-radius: 999px;
}

.label {
  opacity: 0.85;
  font-size: 14px;
}
  
Conic gradient + rotation = spinner

Using gradients on real elements

Gradients become really useful once you stop thinking “big hero background” and start thinking “tiny UI details”. For example: buttons, highlights, subtle shadows, and separators.

Gradients on buttons

A gradient can be a button background, but the button still needs readable text and good contrast. A common trick is to add a slight overlay or a border to keep the shape crisp.

.button {
  background-image: linear-gradient(135deg, #22c55e, #3b82f6, #a855f7);
}
  
.button {
  background-image: linear-gradient(135deg, #f97316, #ef4444, #a855f7);
}
  
.button {
  background-image: radial-gradient(circle at 30% 30%, #38bdf8, #3b82f6 45%, #111);
}
  
*,
::before,
::after {
  box-sizing: border-box;
}

.wrap {
  width: min(560px, 92vw);
  margin-inline: auto;
  border: 3px solid #111;
  border-radius: 18px;
  padding: 22px;
  background: #fff;
  display: grid;
  gap: 14px;
  justify-items: start;
  font-family: ui-monospace, SFMono-Regular, Menlo;
}

.button {
  border: 2px solid rgba(17, 17, 17, 0.35);
  border-radius: 14px;
  padding: 12px 16px;
  font-weight: 700;
  color: #fff;
  text-decoration: none;
  display: inline-block;
  box-shadow: 0px 10px 18px rgba(0, 0, 0, 0.15);
}

.small {
  opacity: 0.85;
  font-size: 14px;
}
  
Gradient button
Try different snippets to change the button background.

Common gradient gotchas

Gradients are background images

  • Use background-image (or background) for gradients.
  • If you also set background-color, it can act as a fallback.

Sharp edges need duplicate stops

If you want a hard edge (like stripes), repeat the same stop position twice:

  • #0ea5e9 0%, #0ea5e9 50%, #a855f7 50%, #a855f7 100%

Percent vs pixel stops

  • Percent stops scale with the element.
  • Pixel stops create fixed-size patterns (great for repeating gradients).

Accessibility and contrast

Gradients can reduce readability because parts of the gradient may be too bright or too dark behind text. If your text sits on a gradient, consider one of these:

  • Put text on a semi-transparent “pill” background (like we did earlier).
  • Use a subtle dark overlay gradient on top of the background.
  • Increase font weight and size, and test contrast across the whole gradient.

Mini checklist for gradients

  1. Decide the type: linear, radial, or conic.
  2. Pick 2–5 colors (more is fine, but start simple).
  3. Add stop positions if you want control (or hard edges).
  4. Layer gradients with commas if you want depth.
  5. For text gradients, use background-clip: text and color: transparent.
  6. For animation, move background-position or rotate the element.

CSS Gradient Conclusion

CSS gradients are a powerful tool for adding color and depth without images. With linear, radial, and conic options, plus layering and animation possibilities, you can create everything from subtle backgrounds to eye-catching text effects. Experiment with stops, positions, and combinations to find your unique style.