CSS Gradient Text: Complete Guide With Cross-Browser Fallbacks
Gradient text looks like it should be simple — set a gradient, apply it to some type, done. Instead it is one of the most commonly botched effects in CSS: solid color blocks where text should be, invisible text on some browsers, and shadows that mysteriously punch through a transparent fill.
The actual technique is three specific properties working together, and almost every failure comes from missing one of them or getting the fallback order wrong. This guide covers the exact working CSS, what is still worth prefixing in 2026, and the fallback pattern that keeps your headline legible even when the effect does not render.
What Makes Gradient Text Different From a Background Gradient
A background gradient fills a box. Gradient text does something more specific: it fills a gradient behind the element, then clips that gradient so only the shape of the rendered letters is visible, then makes the actual text fill transparent so the clipped gradient shows through instead.
Three properties, three jobs:
background / background-image: Defines the gradient itself
background-clip: text: Restricts the gradient to the exact shape of the text
color: transparent (or -webkit-text-fill-color: transparent): Hides the text's own fill so the clipped gradient is what is visible
Miss any one of these three and you get one of two failure modes: a solid rectangle of color (missing the clip), or invisible text (missing the transparency on a browser that does not render the clip).
The Exact CSS You Need
Here is the clean CSS code required to make gradient text work:
- .gradient-text {
- background-image: linear-gradient(90deg, #6366f1, #ec4899);
- background-clip: text;
- -webkit-background-clip: text;
- color: #6366f1; /* fallback color if clipping is not supported */
- -webkit-text-fill-color: transparent;
- }
Notice color is set to a real fallback color, not transparent. This is intentional: -webkit-text-fill-color: transparent is what actually hides the fill in supporting browsers, which means the color value only becomes visible as a fallback in the rare case background-clip is not supported at all. Setting color: transparent directly would make your text invisible on any browser where the clip fails — the opposite of what a fallback should do.
Do You Still Need the -webkit- Prefix?
Less than the research on this topic usually claims. The unprefixed background-clip: text has solid support across modern browsers:
- Chrome: Unprefixed support since Version 120 (Dec 2023)
- Firefox: Unprefixed support since Version 49 (2016)
- Safari: Unprefixed support since Version 15.5 (2022)
- Edge: Unprefixed support since Version 120
- Opera: Unprefixed support since Version 106
If your traffic is entirely on current browser versions, you technically do not need the prefix anymore. But "current versions" is not the same as "all your visitors' browsers" — plenty of real-world traffic still runs Safari <15.5 or Chrome <120, especially on older devices that have not auto-updated. Declaring both costs nothing:
-webkit-background-clip: text;
background-clip: text;
Order matters slightly here — declaring the prefixed version first and unprefixed second ensures modern browsers apply the standard property last and authoritatively.
Why Your Gradient Text Is Not Showing
This is almost always one of three issues:
Missing the clip property entirely. Without background-clip: text (and the -webkit- version for older browsers), the gradient just fills the full bounding box of the element — you will see a solid rectangle, not text-shaped color.
Text is not actually transparent. If color or -webkit-text-fill-color still has a solid value, that solid color paints directly over the clipped gradient, hiding it completely.
The element is a block-level element without proper sizing. On some older browser versions, block-level elements default to spanning the full container width, which stretches the gradient across empty space instead of wrapping tightly to the text. Setting display: inline-block fixes this on the browsers where it is still an issue.
A Safe Fallback for Older Browsers
If a visitor's browser does not support background-clip: text at all, you do not want them staring at invisible text. Wrap the gradient-specific rules in a feature query so unsupported browsers just get your solid fallback color instead:
- .gradient-text {
- color: #6366f1; /* solid fallback, always applied first */
- }
- @supports (background-clip: text) or (-webkit-background-clip: text) {
- .gradient-text {
- background-image: linear-gradient(90deg, #6366f1, #ec4899);
- background-clip: text;
- -webkit-background-clip: text;
- -webkit-text-fill-color: transparent;
- }
- }
Browsers that do not understand @supports at all simply skip the block and keep the solid fallback color — nothing breaks, the text just is not gradient-filled.
Is Gradient Text Accessible?
Yes, for screen readers specifically — the underlying text in the DOM is untouched, so assistive technology reads it exactly like normal text. The technique only changes how it is painted visually, not the markup.
Visual contrast is the real concern. Because a gradient shifts in luminance across its length, one end of your headline might have strong contrast against the background while the other end does not — WCAG compliance has to be checked at both extremes of the gradient, not just the average color. For this reason, gradient text works best on large display headlines rather than dense body copy, where contrast failures are more forgiving at a glance but harder to guarantee at small sizes.
Adding a Shadow to Gradient Text (Without Breaking It)
Applying text-shadow directly to gradient text is the one thing that reliably goes wrong: because the text's own fill is transparent, the shadow can bleed through and render on top of the gradient instead of behind it, muddying the effect.
The reliable fix is a pseudo-element that duplicates the text and carries the shadow on its own, positioned behind the gradient layer:
- .gradient-text {
- position: relative;
- background-image: linear-gradient(90deg, #6366f1, #ec4899);
- background-clip: text;
- -webkit-background-clip: text;
- -webkit-text-fill-color: transparent;
- }
- .gradient-text::before {
- content: attr(data-text);
- position: absolute;
- top: 0;
- left: 0;
- z-index: -1;
- text-shadow: 2px 2px 6px rgba(0, 0, 0, 0.3);
- }
<h1 class="gradient-text" data-text="Your Headline Here">Your Headline Here</h1>
The data-text attribute duplicates your headline text for the pseudo-element, keeping the actual visible content in the real element while the shadow renders on a separate layer behind it.
Build your gradient — and get the CSS, Tailwind, and JSX output ready to paste — at Toolkito's [CSS Gradient Generator](https://toolkito.app/dev-tools/css-gradient-generator).