Reference · CSS text gradients

The declarations, the prefix, and the support matrix.

The text keyword for background-clip is defined in the W3C CSS Backgrounds and Borders Module Level 4 draft, but it was never part of any earlier level. It started life as -webkit-background-clip: text in Safari around 2008, a non-standard WebKit extension designers used for years before the unprefixed form was specified. That history is why a text gradient you write today still carries a vendor prefix almost nothing else in modern CSS requires.

A working text gradient is three declarations, no more.

.headline {
  background: linear-gradient(90deg, #ff2d6f, #7c5cff);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}

The background holds the gradient image. background-clip: text masks that image to the filled glyph shapes instead of the element box. -webkit-text-fill-color: transparent removes the painted text color so the clipped background shows through. GradText emits exactly these lines, in this order, prefixed background-clip first so older WebKit reads it before the standard property overrides.

The three declarations, and why one of them is still prefixed

You’ll see -webkit-background-clip: text and the unprefixed background-clip: text side by side in every text-gradient snippet on the web, and the duplication isn’t cargo-culting.

Chromium and WebKit both shipped the prefixed form long before the spec settled, and a meaningful tail of installed browsers still parses only the -webkit- version. We emit both: prefixed first, standard second. A browser that understands the standard property reads it last and wins; a browser that only knows the prefix has already applied it. -webkit-text-fill-color has no widely supported unprefixed equivalent in shipping browsers, so it stays prefixed alone. Using color: transparent instead is the common mistake; it loses to -webkit-text-fill-color wherever both are set, so we treat color as the visible fallback before any clip applies.

background-clip values and what each one masks

background-clip predates the text keyword. The three original values clip the background to a box edge; text clips to glyphs.

background-clip values and what each one masks
ValueClips the background toTypical use
border-boxThe outer edge of the border (the default)Normal element backgrounds
padding-boxThe inner edge of the borderBackground that stops under the border
content-boxThe content edge, inside the paddingBackground confined to the text area
textThe painted glyph shapesGradient (or image) filled text

Only text needs the prefix dance and the transparent fill. The other three are old, unprefixed, and universal.

Writing the oklch() fill with a HEX fallback that ships

GradText writes gradient stops in either HEX or oklch(), the latter standardized in W3C CSS Color Module Level 4. The reason to reach for oklch() is the midpoint: sRGB interpolation drives complementary color pairs through a low-chroma gray, while OKLCH holds chroma across the transition. (Our sibling tool Graduo derives that color math stop by stop.)

When a stop uses oklch(), we precede the rule with a HEX-equivalent comment:

/* fallback: #ff2d6f -> #7c5cff */
background: linear-gradient(90deg,
  oklch(0.66 0.27 13), oklch(0.58 0.24 285));

A browser that can’t parse oklch() ignores the whole background declaration and the text falls back to its color, which is why we never let color go fully transparent in the copied output. The gradient reads completely differently on a high-contrast display serif than on a geometric sans, so the copied CSS pairs the clip with an @import for whichever of our 60 Google Fonts you picked. If you’re still choosing the typeface, TypeDuo will pair one for you.

Browser support, feature by feature

Support splits cleanly: background-clip: text is old and near-universal once you ship the prefix; oklch() inside a gradient is recent and version-gated. The matrix below is what GradText assumes when it decides whether to warn you about a stop.

Browser support matrix for text-gradient features
FeatureChrome / EdgeFirefoxSafariiOS Safari
-webkit-background-clip: text4+49+4+ (prefixed)4+
background-clip: text (unprefixed)120+ ¹49+14+14+
-webkit-text-fill-color4+49+4+4+
oklch() color111+113+15.4+15.4+
oklch() in gradient stops111+113+16.2+ ²16.2+

¹ Chromium kept background-clip: text behind the prefix far longer than Firefox; until late 2023 you needed -webkit- even on current Chrome, which is the single best reason to keep emitting both forms.
² Safari shipped the oklch() function in 15.4 but the gradient-stop interpolation behavior stabilized at 16.2.

The takeaway for a hero headline: the clip works essentially everywhere a person will see your site, provided you keep the prefix. The OKLCH color is the part with a floor, and that floor is 2023. A browser older than that renders the HEX fallback, so the headline is never blank, only flatter.

Print is the one surface that catches people out. -webkit-text-fill-color: transparent carries into print stylesheets, leaving an invisible headline on paper. If your page is ever printed, override it in an @media print block back to a solid color.

Common questions about text gradients.

Q.01 · Why does a CSS text gradient still need a -webkit- prefix?

Because the technique predates the spec. Safari shipped -webkit-background-clip: text around 2008 as a non-standard WebKit extension, and Chromium picked it up the same way. The unprefixed background-clip: text wasn't specified until the CSS Backgrounds and Borders Level 4 draft, and Chromium kept it behind the prefix until late 2023. A meaningful number of installed browsers still parse only the -webkit- form. GradText emits both, prefixed first and standard second, so a browser that understands the modern property reads it last and wins, while older WebKit has already applied the prefixed version. The -webkit-text-fill-color property has no widely supported unprefixed equivalent in shipping browsers, so it stays prefixed on its own.

Q.02 · What are the three declarations that make a text gradient work?

A working text gradient is exactly three lines. First, a background that holds the gradient image, usually a linear-gradient. Second, background-clip: text, which masks that image to the filled glyph shapes instead of the element box. Third, -webkit-text-fill-color: transparent, which removes the painted text color so the clipped background shows through. GradText writes them in that order, with background-clip prefixed first. A common mistake is reaching for color: transparent instead of -webkit-text-fill-color. The text-fill property wins wherever both are set, so GradText keeps color as the visible fallback that renders before any clip applies, which means the headline is never blank.

Q.03 · How is the text value of background-clip different from border-box or padding-box?

background-clip controls where the element's background image stops. The three original values clip it to a box edge: border-box clips to the outer border edge and is the default, padding-box clips to the inner border edge, and content-box clips to the content edge inside the padding. The text keyword is newer and works differently. Instead of clipping to a rectangle, it clips the background to the painted glyph shapes, so a gradient fills the letters themselves. Only the text value needs the -webkit- prefix and the transparent fill trick. The other three are old, unprefixed, and supported everywhere.

Q.04 · Does oklch() in a gradient break in older browsers?

It degrades rather than breaks. GradText writes stops in HEX or oklch(), and oklch() is the reason a red-to-blue transition stays luminous instead of passing through a muddy gray midpoint. The catch is version support: oklch() inside gradient stops needs Chrome 111+, Firefox 113+, and Safari 16.2+. A browser older than roughly 2023 can't parse oklch(), so it ignores the whole background declaration and the text falls back to its color value. That's why GradText never lets color go fully transparent in the copied output. The headline still renders, just flatter. Each oklch() rule is also preceded by a HEX-equivalent fallback comment so you can swap it manually if you need to.

Q.05 · Why does my gradient headline disappear when the page is printed?

Because -webkit-text-fill-color: transparent carries into print. Most print stylesheets drop background images, so the transparent fill has nothing to clip against and the headline renders invisible on paper. The fix is a print override. Add an @media print block that sets the text color back to a solid value, which restores a readable headline when someone prints the page. This only matters if your page is ever printed or saved to PDF, but it is an easy guard to add and costs nothing on screen, where the gradient still paints normally.