CSS Gradient Text Not Showing? Safari background-clip Fix
If your CSS gradient text shows in Chrome but vanishes in Safari, the cause is almost always a missing WebKit prefix or the wrong target element. Safari requires -webkit-background-clip: text plus -webkit-text-fill-color: transparent, applied directly to the text element, and -webkit-box-decoration-break: clone for multi-line text.
Why gradient text disappears in Safari
The gradient-text trick works by painting a gradient as the element's background, clipping that background to the shape of the glyphs with background-clip: text, and then making the actual text color transparent so the gradient shows through. If any one of those three steps fails, you get either invisible text (transparent fill with no visible background) or a flat rectangle of color (gradient with no clipping).
Safari is stricter than Blink and Gecko about how this is declared. Chrome, Edge, and Firefox have shipped unprefixed background-clip: text (Chromium since version 120 in December 2023), but Safari still relies on the original WebKit-prefixed property for the text keyword. Omit -webkit-background-clip: text and Safari never clips the background, so your transparent text fill leaves nothing on screen.
A second Safari-specific trap is the fill color. Setting color: transparent works in most engines, but Safari honors -webkit-text-fill-color when present, and it overrides color. The robust pattern sets a visible color as a fallback and uses -webkit-text-fill-color: transparent to reveal the gradient only where supported.
The minimal working recipe
Here is the smallest snippet that renders correctly across Safari, Chrome, Edge, and Firefox. Note that linear-gradient itself no longer needs a vendor prefix; only the clip and fill properties do.
.gradient-text {
background: linear-gradient(120deg, #ab4e19, #c99a2e);
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
color: #ab4e19; /* fallback if the gradient never paints */
}
Order matters less than presence: include both the prefixed and unprefixed background-clip so current and legacy engines are covered. The color declaration is insurance. If the background image fails to paint or the browser is ancient, the text stays readable in a solid color instead of disappearing.
Apply it to the text element, not a parent
This is the single most common reason a working snippet breaks when you move it into a real layout. In Chrome and Firefox you can sometimes get away with structures where the clip and the text live close together, but the clip only takes real effect on the element whose own background is being clipped to its own glyphs. Safari is unforgiving here: a gradient set on a wrapper does not clip to the text of a child.
So if your heading is structured as a wrapper with the gradient on the wrapper and the text in a child, Safari shows nothing, because the wrapper's background is being clipped to the wrapper's own (empty) glyph shapes. Move the gradient class directly onto the <h2>, <span>, or <a> that actually contains the characters.
<!-- Broken in Safari: gradient on the parent -->
<div class="gradient-text"><span>Hello</span></div>
<!-- Works: gradient on the element holding the text -->
<h2 class="gradient-text">Hello</h2>
Fixing multi-line gradient text in Safari
Even with correct prefixes, wrapped headings expose another Safari quirk: the first line renders the gradient, but the second and later lines go completely transparent. This happens because an inline box that breaks across lines is split into fragments, and Safari does not extend the clipped background onto the continuation fragments by default.
The fix is box-decoration-break: clone, which tells the engine to give each fragment its own copy of the box decorations (including the clipped background) instead of slicing one continuous box. Safari still needs the -webkit- prefix for this property, so write the prefixed form first and add the unprefixed form for browsers that have dropped the prefix.
.gradient-text {
background: linear-gradient(120deg, #ab4e19, #c99a2e);
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
color: #ab4e19;
-webkit-box-decoration-break: clone;
box-decoration-break: clone;
}
One trade-off to know: with clone, each line gets its own full gradient rather than one gradient flowing continuously across all lines. For most headings and badges this looks fine or even better; if you specifically need a single sweep across wrapped lines, clone changes that behavior and you would need a different technique, such as measuring the rendered width and applying a percentage-based gradient.
Adding an @supports fallback
Because a transparent text fill makes text vanish if the gradient never paints, gate the whole effect behind a feature query. Browsers that cannot clip a background to text simply keep your normal text color, and supporting browsers get the gradient. This is textbook progressive enhancement.
/* Default: plain, always readable */
.gradient-text {
color: #ab4e19;
}
/* Enhanced: only where text-clipping is supported */
@supports (background-clip: text) or (-webkit-background-clip: text) {
.gradient-text {
background: linear-gradient(120deg, #ab4e19, #c99a2e);
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
-webkit-box-decoration-break: clone;
box-decoration-break: clone;
}
}
The or in the feature query matters. Safari historically reported support only for the prefixed property, so testing both background-clip: text and -webkit-background-clip: text covers every engine that can actually do the effect. The main browsers that lack support are Internet Explorer 11 and Opera Mini, and both fall back gracefully to the solid color.
Quick troubleshooting checklist
When gradient text refuses to show, walk this list before rewriting anything. Most failures are one of these five issues.
| Symptom | Likely cause | Fix |
|---|---|---|
| Text invisible in Safari, fine in Chrome | Missing -webkit-background-clip: text | Add the prefixed property |
| Solid color, no gradient | Text fill not transparent | Add -webkit-text-fill-color: transparent |
| Nothing shows even with prefixes | Clip applied to a parent, not the text | Move the class onto the text element |
| First line works, later lines transparent | Fragmented inline box | Add -webkit-box-decoration-break: clone |
| Text gone in unsupported browsers | No fallback | Set a solid color and use @supports |
Build and copy a ready-made gradient with our CSS gradient generator, then paste the linear-gradient value into the recipe above. If you are tweaking the exact stops, the color converter helps translate hex to HSL for smoother transitions, and the image color picker pulls brand colors straight out of a logo or screenshot.
One last note on testing: simulators are not enough. The clip-to-text and multi-line behaviors differ across Safari point releases, so verify on a real iOS device or current desktop Safari before shipping. A snippet that passes in Chrome DevTools device mode can still fail on an actual iPhone.
Frequently Asked Questions
Chrome supports the unprefixed background-clip: text since version 120, but Safari still needs the -webkit-background-clip: text prefix for the text keyword. Add both the prefixed and unprefixed properties so all browsers clip the gradient to the text.
Yes. Safari only clips the background on the element whose own glyphs are being targeted. A gradient set on a parent wrapper clips to the wrapper's empty glyph shape and shows nothing, so put the class directly on the heading, span, or link that holds the characters.
When an inline element breaks across lines, Safari does not extend the clipped background to the continuation fragments. Add -webkit-box-decoration-break: clone (and the unprefixed version) so each line gets its own copy of the gradient.
Set a solid color as a fallback and wrap the gradient styles in an @supports query testing both background-clip: text and -webkit-background-clip: text. Unsupported browsers keep the solid color instead of showing invisible transparent text.