20 CSS Text Gradient Effects08 / 20
Animated Moving Text Gradient Background CSS
A hero section where the gradient background-position animates continuously across a 300%-wide gradient, creating a shifting colour sweep through the text.
Published
The code
<div class="tg-08">
<div class="tg-08__hero">
<div class="tg-08__tag">✦ New — Season 3</div>
<h1 class="tg-08__title">The Future<br>of <span class="tg-08__anim-grad">Interface</span><br>Design</h1>
<p class="tg-08__sub">Shifting gradients create motion and energy without a single line of JavaScript.</p>
</div>
</div><div class="tg-08">
<div class="tg-08__hero">
<div class="tg-08__tag">✦ New — Season 3</div>
<h1 class="tg-08__title">The Future<br>of <span class="tg-08__anim-grad">Interface</span><br>Design</h1>
<p class="tg-08__sub">Shifting gradients create motion and energy without a single line of JavaScript.</p>
</div>
</div>.tg-08,
.tg-08 *,
.tg-08 *::before,
.tg-08 *::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.tg-08 ::selection {
background: #7c3aed55;
color: #fff;
}
.tg-08 {
--c1: #f0abfc;
--c2: #818cf8;
--c3: #38bdf8;
--c4: #34d399;
--bg: #0a0a12;
--text: #f8fafc;
--muted: #94a3b8;
font-family: system-ui, -apple-system, sans-serif;
background: var(--bg);
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding: 48px 24px;
}
.tg-08__hero {
text-align: center;
max-width: 600px;
}
.tg-08__tag {
display: inline-block;
font-size: .75rem;
font-weight: 700;
letter-spacing: .1em;
color: var(--muted);
margin-bottom: 24px;
}
.tg-08__title {
font-size: clamp(2.5rem, 8vw, 4.5rem);
font-weight: 900;
line-height: 1.08;
letter-spacing: -.04em;
color: var(--text);
margin-bottom: 20px;
}
/*
Moving gradient: background-size is 300% wide so the
gradient has room to travel. background-position animates
from 0% to 100%, which pans across the extended gradient.
background-clip:text exposes it through the letterforms.
*/
.tg-08__anim-grad {
background: linear-gradient(
90deg,
var(--c1) 0%,
var(--c2) 25%,
var(--c3) 50%,
var(--c4) 75%,
var(--c1) 100%
);
background-size: 300% 100%;
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
color: transparent;
animation: tg-08-shift 4s linear infinite;
}
@keyframes tg-08-shift {
0% {
background-position: 0% 50%;
}
100% {
background-position: 100% 50%;
}
}
.tg-08__sub {
font-size: 1rem;
color: var(--muted);
line-height: 1.7;
max-width: 480px;
margin: 0 auto;
}
@media (prefers-reduced-motion: reduce) {
.tg-08__anim-grad {
animation: none;
background-position: 0% 50%;
}
}.tg-08,
.tg-08 *,
.tg-08 *::before,
.tg-08 *::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.tg-08 ::selection {
background: #7c3aed55;
color: #fff;
}
.tg-08 {
--c1: #f0abfc;
--c2: #818cf8;
--c3: #38bdf8;
--c4: #34d399;
--bg: #0a0a12;
--text: #f8fafc;
--muted: #94a3b8;
font-family: system-ui, -apple-system, sans-serif;
background: var(--bg);
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding: 48px 24px;
}
.tg-08__hero {
text-align: center;
max-width: 600px;
}
.tg-08__tag {
display: inline-block;
font-size: .75rem;
font-weight: 700;
letter-spacing: .1em;
color: var(--muted);
margin-bottom: 24px;
}
.tg-08__title {
font-size: clamp(2.5rem, 8vw, 4.5rem);
font-weight: 900;
line-height: 1.08;
letter-spacing: -.04em;
color: var(--text);
margin-bottom: 20px;
}
/*
Moving gradient: background-size is 300% wide so the
gradient has room to travel. background-position animates
from 0% to 100%, which pans across the extended gradient.
background-clip:text exposes it through the letterforms.
*/
.tg-08__anim-grad {
background: linear-gradient(
90deg,
var(--c1) 0%,
var(--c2) 25%,
var(--c3) 50%,
var(--c4) 75%,
var(--c1) 100%
);
background-size: 300% 100%;
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
color: transparent;
animation: tg-08-shift 4s linear infinite;
}
@keyframes tg-08-shift {
0% {
background-position: 0% 50%;
}
100% {
background-position: 100% 50%;
}
}
.tg-08__sub {
font-size: 1rem;
color: var(--muted);
line-height: 1.7;
max-width: 480px;
margin: 0 auto;
}
@media (prefers-reduced-motion: reduce) {
.tg-08__anim-grad {
animation: none;
background-position: 0% 50%;
}
}Here's a working CSS Text Gradient Effect from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Animated Moving Text Gradient Background CSS
Source: https://codefronts.com/motion/css-text-gradient-effect/animated-moving-text-gradient-background-css/
A hero section where the gradient background-position animates continuously across a 300%-wide gradient, creating a shifting colour sweep through the text.
## HTML
```html
<div class="tg-08">
<div class="tg-08__hero">
<div class="tg-08__tag">✦ New — Season 3</div>
<h1 class="tg-08__title">The Future<br>of <span class="tg-08__anim-grad">Interface</span><br>Design</h1>
<p class="tg-08__sub">Shifting gradients create motion and energy without a single line of JavaScript.</p>
</div>
</div>
```
## CSS
```css
.tg-08,
.tg-08 *,
.tg-08 *::before,
.tg-08 *::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.tg-08 ::selection {
background: #7c3aed55;
color: #fff;
}
.tg-08 {
--c1: #f0abfc;
--c2: #818cf8;
--c3: #38bdf8;
--c4: #34d399;
--bg: #0a0a12;
--text: #f8fafc;
--muted: #94a3b8;
font-family: system-ui, -apple-system, sans-serif;
background: var(--bg);
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding: 48px 24px;
}
.tg-08__hero {
text-align: center;
max-width: 600px;
}
.tg-08__tag {
display: inline-block;
font-size: .75rem;
font-weight: 700;
letter-spacing: .1em;
color: var(--muted);
margin-bottom: 24px;
}
.tg-08__title {
font-size: clamp(2.5rem, 8vw, 4.5rem);
font-weight: 900;
line-height: 1.08;
letter-spacing: -.04em;
color: var(--text);
margin-bottom: 20px;
}
/*
Moving gradient: background-size is 300% wide so the
gradient has room to travel. background-position animates
from 0% to 100%, which pans across the extended gradient.
background-clip:text exposes it through the letterforms.
*/
.tg-08__anim-grad {
background: linear-gradient(
90deg,
var(--c1) 0%,
var(--c2) 25%,
var(--c3) 50%,
var(--c4) 75%,
var(--c1) 100%
);
background-size: 300% 100%;
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
color: transparent;
animation: tg-08-shift 4s linear infinite;
}
@keyframes tg-08-shift {
0% {
background-position: 0% 50%;
}
100% {
background-position: 100% 50%;
}
}
.tg-08__sub {
font-size: 1rem;
color: var(--muted);
line-height: 1.7;
max-width: 480px;
margin: 0 auto;
}
@media (prefers-reduced-motion: reduce) {
.tg-08__anim-grad {
animation: none;
background-position: 0% 50%;
}
}
```Here's a working CSS Text Gradient Effect from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Animated Moving Text Gradient Background CSS
Source: https://codefronts.com/motion/css-text-gradient-effect/animated-moving-text-gradient-background-css/
A hero section where the gradient background-position animates continuously across a 300%-wide gradient, creating a shifting colour sweep through the text.
## HTML
```html
<div class="tg-08">
<div class="tg-08__hero">
<div class="tg-08__tag">✦ New — Season 3</div>
<h1 class="tg-08__title">The Future<br>of <span class="tg-08__anim-grad">Interface</span><br>Design</h1>
<p class="tg-08__sub">Shifting gradients create motion and energy without a single line of JavaScript.</p>
</div>
</div>
```
## CSS
```css
.tg-08,
.tg-08 *,
.tg-08 *::before,
.tg-08 *::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.tg-08 ::selection {
background: #7c3aed55;
color: #fff;
}
.tg-08 {
--c1: #f0abfc;
--c2: #818cf8;
--c3: #38bdf8;
--c4: #34d399;
--bg: #0a0a12;
--text: #f8fafc;
--muted: #94a3b8;
font-family: system-ui, -apple-system, sans-serif;
background: var(--bg);
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding: 48px 24px;
}
.tg-08__hero {
text-align: center;
max-width: 600px;
}
.tg-08__tag {
display: inline-block;
font-size: .75rem;
font-weight: 700;
letter-spacing: .1em;
color: var(--muted);
margin-bottom: 24px;
}
.tg-08__title {
font-size: clamp(2.5rem, 8vw, 4.5rem);
font-weight: 900;
line-height: 1.08;
letter-spacing: -.04em;
color: var(--text);
margin-bottom: 20px;
}
/*
Moving gradient: background-size is 300% wide so the
gradient has room to travel. background-position animates
from 0% to 100%, which pans across the extended gradient.
background-clip:text exposes it through the letterforms.
*/
.tg-08__anim-grad {
background: linear-gradient(
90deg,
var(--c1) 0%,
var(--c2) 25%,
var(--c3) 50%,
var(--c4) 75%,
var(--c1) 100%
);
background-size: 300% 100%;
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
color: transparent;
animation: tg-08-shift 4s linear infinite;
}
@keyframes tg-08-shift {
0% {
background-position: 0% 50%;
}
100% {
background-position: 100% 50%;
}
}
.tg-08__sub {
font-size: 1rem;
color: var(--muted);
line-height: 1.7;
max-width: 480px;
margin: 0 auto;
}
@media (prefers-reduced-motion: reduce) {
.tg-08__anim-grad {
animation: none;
background-position: 0% 50%;
}
}
```How this works
The moving gradient uses an extended background-size: 300% 100% which makes the gradient three times wider than the element. The @keyframes tg-08-shift animation moves background-position from 0% 50% to 100% 50% linearly and infinitely. Because the gradient is cyclic (it repeats the first colour at 100%), the transition is seamless with no visible seam.
Only the background-position property is animated. This is a compositor-friendly operation — the browser can perform it without triggering layout or paint phases. Combined with -webkit-background-clip: text, the shifting position is visible only through the letterforms, creating the illusion of light sweeping through the text.
Make it yours
- Control animation speed by editing
4sinanimation: tg-08-shift 4s linear infinite— slower values (8s) feel meditative, faster (1.5s) feel energetic. - Add more colour stops to the gradient — insert hues between existing stops and expand
background-sizeto400%to keep the sweep speed consistent with more colours. - Change
lineartiming toease-in-outfor a breathing quality — the sweep accelerates into and out of the highlight band instead of moving at constant speed. - Apply the same animated gradient to a subtitle or tag by adding the
tg-08__anim-gradclass, adjusting the gradient stops to complementary colours for a multi-element sequence. - Pause the animation on hover by adding
.tg-08__anim-grad:hover { animation-play-state: paused; }so users can 'freeze' the gradient at their preferred colour point.
Gotchas — read before shipping
- The
background-positionanimation approach requiresbackground-size: 300% 100%— if you forget to set this, the gradient won't appear to move because the default 100% size leaves no room for the position to scroll. - Using
lineartiming on the position animation creates a seamless loop only when the gradient's first and last colour stops match. If they differ, the jump at the loop boundary will be visible — always make the final stop equal the initial stop. - On Safari, very long text strings with animated
background-positionandbackground-clip: textcan cause a brief repaint flash on loop iteration. Limit the animation to short display words (<10 characters) for the smoothest result.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 69+ | 12.1+ | 83+ | 69+ |
background-position animation on background-clip:text elements is reliable in modern browsers; avoid pairing with simultaneous transforms on the same element in Safari.