CSS and web

Gradient text in CSS, done well

Three lines of CSS put a gradient inside your letters. Making it readable, robust and tasteful takes a few more, and knowing when to leave the text plain.

GradientlyVerified Gradiently account··5 min read
Cover: Mistral Reel · GR·SXXT·96

The short version

  • Gradient text in CSS works by painting a gradient as the element's background, clipping it to the shape of the letters with background-clip: text, and making the text colour transparent.
  • Always set a solid text colour first, and apply the transparent colour only inside an @supports check, so the words never vanish.
  • Every part of the gradient needs enough contrast against the background, so check the lightest and darkest stops, not just one.
  • Gradient text suits short display lines at large sizes, and works poorly for body copy, links and small labels.
  • Adding box-decoration-break: clone gives each line of a wrapped inline element its own full gradient.
On this page

Gradient text in CSS is made by painting a gradient as the background of the text element, clipping that background to the letter shapes with background-clip: text, and making the text itself transparent so the gradient shows through. It takes three declarations, works in every current browser, and stays real, selectable, searchable text rather than an image.

css
.gradient-text {
  background-image: linear-gradient(90deg, #6d28d9, #be185d);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
The core technique. The prefixed line keeps older Safari and Chromium versions happy.
Violet to rose, for light pageslinear-gradient(90deg, #6d28d9, #be185d)
The gradient inside those letters. Both ends are dark enough to read on white.

The rest of this guide covers what the three-line version gets wrong: missing fallbacks, contrast, multi-line text, clipped descenders, and the design question of when gradient text helps at all. For the look of gradient lettering in social and brand work rather than on the web, see text effects.

A robust gradient text recipe with fallbacks

If a browser applies color: transparent but not the clip, the text disappears. Guard against it: give the element a solid colour taken from the gradient, then switch to the transparent version only when the browser confirms support. Add a reset for forced colours mode, where the system replaces your colours and the text must stay visible.

css
.gradient-text {
  color: #6d28d9; /* solid fallback from the gradient */
}

@supports (background-clip: text) or (-webkit-background-clip: text) {
  .gradient-text {
    background-image: linear-gradient(90deg, #6d28d9, #be185d);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
  }
}

@media (forced-colors: active) {
  .gradient-text {
    background: none;
    color: CanvasText;
  }
}
Solid colour first, gradient only where supported, and a system colour when the user forces their own.

The MDN page on background-clip documents the text value and its current support.

Contrast: check both ends of the gradient

A contrast checker takes one text colour, but gradient text has many. The words are only as readable as their weakest part, so check the lightest stop and the darkest stop against the background, and look at the middle too, because an sRGB blend can dip lighter or duller than either end. For large display text, WCAG asks for at least 3:1; for normal text, 4.5:1. Colour contrast explains the ratios.

Text gradients whose stops all clear 5:1 on the background named. On white, each stop measures above 5:1; on #0b0b12, above 7:1.

Fixing multi-line gradient text and clipped letters

On an inline element that wraps, the browser lays one background across all the lines as if they were a single strip, so the first line gets the start of the gradient and the last line gets the end. Usually you want each line to carry the full gradient. box-decoration-break: clone does that. On block elements, such as a heading, the gradient already spans the whole box, so a long gradient across a wide heading may show only its middle on short lines.

css
.gradient-text {
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
  /* stop descenders being cut off */
  line-height: 1.15;
  padding-block-end: 0.08em;
}
Each line gets its own full gradient, and the tails of g, j, p and y stay inside the painted area.

Clipped descenders are the other surprise. The background only paints the element's box, so with a very tight line-height, the parts of letters that hang below it are left transparent and vanish. A line height of about 1.1 or a little bottom padding fixes it. Italic display faces can lose the tip of their last letter on the right for the same reason; a touch of inline padding helps.

When gradient text works, and when it does not

Avoid

  • Body copy, where the colour shift slows reading
  • Links and buttons, where colour signals state
  • Small labels under about 24px, where the gradient is invisible anyway
  • Rainbow gradients with five or more hues
  • Gradient text on a gradient background

Use it for

  • One word or short phrase in a large headline
  • A product or brand name in a hero
  • Big numbers in a stat block
  • Two or three related hues at similar lightness
  • Plain, calm backgrounds that let the letters lead

A good rule: gradient text is an accent, like italics. One highlighted word in a headline draws the eye; a whole paragraph of it tires it. Heavy weights help, because thin strokes do not show enough colour to read as a gradient. If the rest of the page already uses gradient backgrounds, flat type is usually the stronger choice; text on gradient backgrounds covers that case.

Animating gradient text

To make colour flow through the letters, make the background larger than the text and move it. Size it at 200% wide and animate background-position back and forth with alternate, so there is never a jump where the loop restarts. Respect reduced motion settings, and keep it slow: a shimmer every few seconds reads as polish, a fast cycle reads as a warning.

css
.gradient-text--flow {
  background-image: linear-gradient(90deg, #6d28d9, #be185d, #c2410c);
  background-size: 200% 100%;
  animation: flow 6s ease-in-out infinite alternate;
}

@keyframes flow {
  from { background-position: 0% 50%; }
  to   { background-position: 100% 50%; }
}

@media (prefers-reduced-motion: reduce) {
  .gradient-text--flow { animation: none; }
}
Colour drifting back and forth through the words. Combine it with the clip and fallback from the recipe above.

The same background tricks power animated gradients in CSS more broadly, and gradient outlines rather than fills are covered in CSS gradient borders.

Questions people ask

How do I make gradient text in CSS?

Set a gradient as background-image, add -webkit-background-clip: text and background-clip: text, and set color: transparent. Put a solid colour outside an @supports check as a fallback.

Why is my gradient text invisible?

The text is transparent but the background is not being clipped, usually because the clip declaration is missing, misspelled or unsupported. Apply color: transparent only inside @supports (background-clip: text).

Is gradient text accessible?

It can be, if every part of the gradient has enough contrast with the background and the text stays real text. Check the lightest and darkest stops, and reset colours in forced colours mode.

Why are the bottoms of my letters cut off?

The clipped background only covers the element's box, so a tight line height leaves descenders outside it. Raise the line height to about 1.1 or add a little bottom padding.

Can I use gradient text in emails?

Support for background-clip: text is patchy across email clients, so use a solid colour or an image with alt text there. See gradients in email.

Share this guide

Written by GradientlyVerified Gradiently account

The team behind Gradiently, a design tool built around Marks: living gradients that make everything you design look like yours.

See our profile