Gradient Flow
Continuously scrolls a multicolor gradient over any text element — pure CSS, no JavaScript, seamless loop achieved by repeating the first color stop.
You'll get access to the interactive demo with a free account.
This effect is part of Effect.Labs — 811 vanilla effects, some free, some premium. Text has 56 effects, including 4 free. Explore the category →
3 usage examples



How it works
The effect relies on background-clip: text (with -webkit-text-fill-color: transparent): the gradient is positioned on the element background then clipped to the exact glyph shapes, without any SVG mask or canvas pixel. The page background shows through between the characters.
The gradient is declared 3× wider than the element (background-size: 300% 100%). The @keyframes gradientFlowAnim slides background-position from 0% 50% to 300% 50% over 3 s in linear, infinite mode: exactly one full gradient cycle per iteration.
For an invisible loop junction, the first color (#ff0080) is repeated as the last stop in the linear-gradient. When the position returns to 0%, the displayed hue is identical to the last pixel of the previous iteration. Without this repeat, a sharp contrast flash betrays the loop.
The effect is 100% CSS, with no JS and no dependency. It applies to any text element (<h1>, <span>, <a>, <button>) by adding the two classes or copying the properties directly. Multiple instances on the same page run independently via the same @keyframes, with no conflicts.
Accessibility
- prefers-reduced-motion not handled: no media query stops the animation when the OS signals a reduced-motion preference. To fix this, wrap the animation rule in
@media (prefers-reduced-motion: no-preference) { .text-gradient-flow { animation: … } }. - Contrast not guaranteed off dark backgrounds: the default colors (pink
#ff0080, orange#ff8c00, teal#40e0d0) pass WCAG AA on#0a0a0f, but the ratio shifts with every color stop — test your palette with a contrast tool before deploying on light or saturated backgrounds. - No ARIA attributes in the minimal structure: the text element stays in the normal flow and is read as-is by screen readers. If it is purely decorative, add
aria-hidden="true". - No keyboard interaction or focus management by the effect: if the text is a link or button, define
:focus-visiblestyling independently. - The animation produces no flicker or flash (continuous background pan, < 3 Hz) — it meets WCAG 2.3.1.
Browser compatibility
Requires background-clip: text (CSS4) and -webkit-text-fill-color. The background shorthand with / 300% 100% text as clip value requires Chrome 116+ / Edge 116+ / Safari 16.4+ / Firefox 122+.
On older browsers that ignore <code>background-clip: text</code>, text renders with its inherited CSS color (white on dark background by default). No JS crashes, the page stays readable. For broader compatibility, use the longhand properties with <code>-webkit-background-clip: text</code> and <code>-webkit-text-fill-color: transparent</code>.
The code
HTML structure to paste into your page (CSS + JS available with a premium account):
<div class="demo-preview">
<!-- Text with animated gradient -->
<span class="demo-text text-gradient-flow">
Your text here
</span>
</div>
<!-- Without wrapper: apply directly to any element -->
<h1 class="demo-text text-gradient-flow">Animated heading</h1>
Full HTML + CSS + JS, copy-paste ready — with hundreds of premium effects.
Customize
Options passed to the API or data-* attributes:
| Option / property | Default | Effect |
|---|---|---|
| Gradient color stops | #ff0080, #ff8c00, #40e0d0, #ff0080 | Edit the stops in linear-gradient(90deg, …). The first and last stops must be identical for a seamless loop. |
| background-size: 300% | 300% | Gradient width relative to the element. Increase to 400–600% for a longer cycle with more intermediate colors and smoother transitions. |
| animation-duration (3s) | 3s | Duration of one full cycle. 2s = fast and energetic; 6s = slow and elegant. Match it to the visual mood of the page. |
| animation-timing-function (linear) | linear | linear for consistent scrolling (recommended for infinite loops). ease-in-out creates a subtle pulse — more visible but non-linear at the loop point. |
| animation-direction (normal) | normal | Switch to reverse to flip the scroll direction (right → left). Useful to mirror two adjacent elements for a symmetry effect. |
| font-size: 2.5rem | 2.5rem | Text size on .demo-text. The effect is most striking at large sizes (≥ 2rem); on small or thin text, gradient colors appear washed out. |
| font-weight: 800 | 800 | Weight on .demo-text. High weights (700–900) maximize the gradient fill surface and make colors more vibrant on wide typefaces. |
FAQ
demo-text text-gradient-flow to each element. Being 100% CSS, each instance runs independently via the same @keyframes gradientFlowAnim; there is no JS to initialize and no conflict between instances.background-position returns to 0%, the displayed hue is identical to the last pixel of the previous iteration. Without this repeat, a sharp contrast flash betrays the loop point — most visible at fast speeds.background-clip: text lets the page background show through the glyph shapes — there is no fill background, only the gradient colors on the characters. On a white background, the default colors (pink, orange, teal) remain visible but WCAG AA contrast is not guaranteed — test your palette with a contrast tool before deploying.