← Back to gallery
CSS

Gradient-Clipped Rainbow Text

A multicolor linear-gradient clipped into live text via background-clip, with a static fallback for engines that don't support it. Three palettes: a balanced spectrum hero, a warmer festival CTA, and a muted dashboard treatment.

rainbow-textgradient-textbackground-cliptext-filldrop-shadowsupports-fallbackprefers-reduced-motion

Gradient text · clipped color bands

Gradient-Clipped Rainbow Text

A multicolor background is clipped into live <text>, with restrained color stops and a dark backing surface so the label remains readable through the loop. Three variants demonstrate a balanced spectrum hero, a warmer festival CTA, and a muted dashboard treatment.

Balanced color route

Spectrum Hero

A balanced full-spectrum band travels across large display text without using external image assets or replacing the accessible text node. Cool and warm stops repeat at both ends so the background-position can loop without a hard seam.

  • rainbow bands
  • live text
  • contrast guard

Higher energy label

Festival CTA

A brighter CTA treatment uses warmer middle stops but keeps a stable fallback color and no layout-affecting transforms. Useful for promotional labels where the movement should feel expressive while the DOM text remains selectable.

  • CTA text
  • warm stops
  • no transform

Restrained dashboard color

Data Spectrum

A calmer variant lowers the glow and stretches the background span so dashboard text gets color without noisy flicker. Slower color pass works better for repeated UI surfaces because users can scan labels without chasing movement.

  • dashboard
  • slow loop
  • muted spectrum

Rainbow inspector

Spectrum Hero

  • rainbow bands
  • live text
  • contrast guard

A balanced full-spectrum band travels across large display text without using external image assets or replacing the accessible text node. Cool and warm stops repeat at both ends so the background-position can loop without a hard seam.

Helped you ship something? 🐟 Send my cat a churu

.gradient-text {
  /* Static fallback for engines without background-clip: text */
  color: #dbeafe;
}

@supports ((background-clip: text) or (-webkit-background-clip: text)) {
  .gradient-text {
    background-image: linear-gradient(90deg, #67e8f9 0%, #a78bfa 18%, #f472b6 34%, #fbbf24 50%, #34d399 66%, #67e8f9 82%, #a78bfa 100%);
    background-size: 300% 100%;
    background-position: 0% 50%;
    background-clip: text;
    -webkit-background-clip: text;
    color: transparent;
    -webkit-text-fill-color: transparent;
    filter: drop-shadow(0 0 14px rgba(244, 114, 182, 0.26));
    animation: gradient-text-sweep 4.80s linear infinite;
  }
}

@keyframes gradient-text-sweep {
  from { background-position: 0% 50%; }
  to   { background-position: 100% 50%; }
}

@media (prefers-reduced-motion: reduce) {
  .gradient-text {
    animation: none;
    background-position: 55% 50%;
  }
}

How to make this

Gradient-clipped rainbow text keeps one live text node, applies transparent fill only inside @supports, and sweeps an oversized multicolor background through the glyphs.

html
1<h1 class="rainbow-clip">Spectrum UI</h1> <style>.rainbow-clip {  margin: 0;6  color: #dbeafe;  font: 900 clamp(2.4rem, 12vw, 5rem)/.92 ui-sans-serif, system-ui;  letter-spacing: 0;}10@supports ((background-clip: text) or (-webkit-background-clip: text)) {  .rainbow-clip {12    background-image: linear-gradient(90deg,      #67e8f9 0%, #a78bfa 18%, #f472b6 34%,      #fbbf24 50%, #34d399 66%, #67e8f9 82%,      #a78bfa 100%);16    background-size: 300% 100%;    background-position: 0% 50%;    background-clip: text;    -webkit-background-clip: text;    color: transparent;    -webkit-text-fill-color: transparent;22    filter: drop-shadow(0 0 14px rgba(244, 114, 182, .26));    animation: rainbow-clip-recipe-sweep 4.8s linear infinite;  }}@keyframes rainbow-clip-recipe-sweep {  from { background-position: 0% 50%; }  to { background-position: 100% 50%; }}30@media (prefers-reduced-motion: reduce) {  .rainbow-clip {    animation: none;    background-position: 55% 50%;  }}36@media (forced-colors: active) {  .rainbow-clip {    color: CanvasText;    -webkit-text-fill-color: currentColor;    background: none;    filter: none;  }}</style>

Annotated snippet

  1. Line 1The headline remains one real text node. The rainbow is paint clipped into glyphs, not an image replacement or duplicated decorative text.
    PitfallIs rainbow gradient text accessible?

    It can be if the text remains a real DOM node, contrast stays readable at every color frame, and forced-colors or unsupported clipping falls back to a solid color.

  2. Line 6Set a normal fallback color before clipping. Unsupported browsers, forced colors, and print styles need readable text before any enhancement applies.
    PitfallWhy did my rainbow text vanish?

    Transparent fill was probably applied outside a support guard. Set a normal color first, then move background clipping, color: transparent, and -webkit-text-fill-color into an @supports block.

  3. Line 10The transparent fill is gated by @supports. This prevents the common failure where text becomes transparent in a browser that cannot clip the background.

    before simulates what an unsupported browser shows: color: transparent is applied but background-clip: text is missing, so the gradient renders as a rectangle behind invisible text — the phrase "Live text" disappears completely. after sets a readable colour as the baseline and only switches to transparent + clip inside @supports, so unsupported browsers fall back to readable solid text while modern browsers still get the rainbow.

    PitfallWhy did my rainbow text vanish?

    Transparent fill was probably applied outside a support guard. Set a normal color first, then move background clipping, color: transparent, and -webkit-text-fill-color into an @supports block.

  4. Line 12The color stops repeat cool colors at both ends. That makes the 0% and 100% background positions meet without a harsh rainbow seam.

    Same background-position 0% → 100% sweep on both. before starts in cyan and ends in amber — when the loop snaps back, the right edge (amber) suddenly becomes the left edge (cyan), a visible colour jump every cycle. after repeats cyan at both ends of the gradient, so the loop point matches and the sweep reads continuous.

    PitfallHow wide should the gradient background be?

    Use a background-size wider than the text, often 260% to 340%. Wider canvases create calmer color travel; narrow canvases make the glyphs look like a static rainbow sticker.

  5. Line 16background-size: 300% gives the color band a runway. A 100% canvas tends to look like static rainbow fill rather than a controlled sweep.
    PitfallHow wide should the gradient background be?

    Use a background-size wider than the text, often 260% to 340%. Wider canvases create calmer color travel; narrow canvases make the glyphs look like a static rainbow sticker.

  6. Line 22The glow is paint work, so keep it modest. A small drop-shadow can lift display text; a large blur makes the sweep noisy and expensive.
    PitfallIs animating clipped gradient text performant?

    It is paint work because background-position changes. Use it for a small number of display labels, keep glow restrained, and avoid looping it across long paragraphs or dense tables.

  7. Line 30Reduced motion freezes the gradient at a readable midpoint. The text stays clipped and visible, but the color bands stop traveling.
    PitfallWhich browsers need WebKit-prefixed text clipping?

    Safari and WebKit-based browsers still need -webkit-background-clip: text and -webkit-text-fill-color: transparent. Keep the unprefixed properties and a plain fallback color as well.

  8. Line 36Forced-colors mode restores system text color and removes clipping. High-contrast users should get normal text, not transparent decorative paint.
    PitfallIs rainbow gradient text accessible?

    It can be if the text remains a real DOM node, contrast stays readable at every color frame, and forced-colors or unsupported clipping falls back to a solid color.

Notes

Overview

A multicolor linear gradient clipped into live text via background-clip: text — a vivid spectrum sweeps through the glyphs without any per-letter spans or canvas tricks. A static fallback color renders for engines that do not support the property, so unsupported browsers see a solid (non-invisible) text instead of nothing.

When to use it

Reach for rainbow-clipped text on celebratory or “complete me” product surfaces — checkout completion, achievement unlock, pride banners. Skip it for utility chrome; the vivid spectrum reads as marketing, not information. Skip it for low-contrast surfaces — even moderate stops drop below WCAG AA against a busy background.

How it works

Set background-image on the text to a multi-stoplinear-gradient(90deg, red, orange, yellow, green, cyan, violet) with background-size: 200% 100% (oversized) so the gradient extends past the glyphs. Clip the background to the text shape with background-clip: text + -webkit-background-clip: text, then set color: transparent + -webkit-text-fill-color: transparent so the glyph fill comes from the clipped gradient. Animate background-position from 0% 50% to 100% 50% for a slow spectrum drift; the colors visible inside each glyph shift as the gradient slides under the clip.

Production gotchas

The @supports feature query is non-negotiable — omit it and Firefox versions without background-clip: text render the text invisible (transparent color + no clip = nothing). On Safari iOS the -webkit-text-fill-color prefix is still required alongside the unprefixed color: transparent. Saturated spectrum stops on a busy background can drop below WCAG AA contrast — verify the gradient against the surface at both rest and peak animation positions, not just one frame.

Accessibility

The text node is real DOM throughout — screen readers, copy-paste, and search engines all see the string normally. Under prefers-reduced-motion: reduce pause the gradient at a middle position so the text still reads as rainbow-clipped without the sliding motion. Provide a sufficiently-contrasting fallback color for @supports-less browsers.

References

Implementation depth

Rainbow text needs restraint in both palette and surface. Keep the phrase short, clip the gradient to real text, and use a solid fallback so unsupported browsers never render transparent invisible copy.

The gradient should support the content hierarchy. If every heading uses a rainbow treatment, no heading is special. Reduced motion should pin the gradient rather than animating color movement through body-sized text.