Animated Gradient Backgrounds, Explained
An animated css gradient background turns a flat page section into something that quietly breathes and drifts. The technique is pure CSS: you make a gradient larger than its container, then animate its background position on a loop so the colors appear to move. No JavaScript, no images, no libraries. TooStamply's gradient generator has a dedicated animation mode that outputs the full CSS — gradient, sizing, and keyframes — in one copy.
This guide shows how css gradient animation works, gives you copy-paste recipes, and covers the performance and accessibility details that separate a polished effect from a janky one.
How Animated Gradients Work
The trick has three parts:
- Define a multi-color
linear-gradient(). - Set
background-sizelarger than the element (commonly400% 400%) so there's room to slide. - Animate
background-positionwith@keyframeson an infinite loop.
Here's the canonical gradient animation css recipe:
.animated-gradient {
background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);
background-size: 400% 400%;
animation: gradient 15s ease infinite;
}
@keyframes gradient {
0% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
100% { background-position: 0% 50%; }
}
Because the animation returns to its starting position at 100%, the loop is seamless — there's no visible jump when it restarts.
Animation Speed
Duration changes the whole mood of the effect:
| Duration | Feel | Good for |
|---|---|---|
| 20–30s | Subtle, professional | Corporate and SaaS sites |
| 10–15s | Noticeable, not distracting | Landing pages, hero sections |
| 3–5s | Energetic | Gaming, music, and event sites |
When in doubt, go slower. A gradient that moves too fast reads as busy and pulls attention away from your copy.
A Radial Variation
You aren't limited to linear gradients. Animating the position of a animated gradient background built from a radial gradient produces a soft, pulsing spotlight:
.pulse {
background: radial-gradient(circle at 50% 50%, #7f5af0, #2cb67d);
background-size: 200% 200%;
animation: pulse 12s ease-in-out infinite;
}
@keyframes pulse {
0%, 100% { background-position: 0% 0%; }
50% { background-position: 100% 100%; }
}
For layered, mesh-style motion you can combine several radial gradients — see the mesh gradient guide for how to place the points.
OKLCH for Cleaner Motion
Animating between distant hues in sRGB can drag the midpoint through a muddy gray. Building the gradient in OKLCH keeps lightness steady across the sweep, so the motion stays vivid the whole way:
.animated-oklch {
background: linear-gradient(-45deg,
oklch(0.70 0.18 20),
oklch(0.70 0.18 200),
oklch(0.70 0.18 320));
background-size: 400% 400%;
animation: gradient 18s ease infinite;
}
The OKLCH gradient guide goes deeper on why this works.
Animating the Angle Instead of the Position
Shifting background-position is the classic approach, but it's not the only one. With modern CSS you can register a custom angle property and animate the gradient's direction itself, which produces a rotating sweep rather than a slide:
@property --angle {
syntax: '<angle>';
initial-value: 0deg;
inherits: false;
}
.rotating {
background: linear-gradient(var(--angle), #ee7752, #23a6d5);
animation: spin 8s linear infinite;
}
@keyframes spin {
to { --angle: 360deg; }
}
This technique is especially nice for animated borders and glowing rings, since the color appears to travel around the element. The generator can produce either style — a position slide or an angle spin — depending on the effect you pick.
Layering for Depth
A single animated gradient is clean, but layering two or three at different speeds gives a richer, less repetitive feel. Because CSS lets you stack multiple background images, you can animate each layer independently and let them drift past one another:
.layered {
background:
radial-gradient(at 20% 30%, rgba(127,90,240,0.6) 0, transparent 50%),
radial-gradient(at 80% 70%, rgba(44,182,125,0.6) 0, transparent 50%),
#0f0c29;
background-size: 200% 200%, 180% 180%, auto;
animation: layerA 20s ease infinite, layerB 26s ease infinite;
}
The differing durations mean the layers never quite line up the same way twice, so the motion feels organic. This is the same idea behind mesh gradients — the mesh gradient guide covers the static version, and the animation mode brings it to life.
Performance Considerations
Animated gradients are cheap when done right, but a few habits keep them smooth:
- Animating
background-positionis GPU-friendly and generally performant. - Avoid stacking heavy content directly on an animating layer to prevent repaint thrash.
- Add
will-change: background-positionto hint the browser, but only on elements that are actually animating. - Keep the number of simultaneously animating full-screen gradients low on a single page.
Respect Reduced Motion
Some users get motion sickness or simply prefer stillness. Always honor their system setting:
@media (prefers-reduced-motion: reduce) {
.animated-gradient {
animation: none;
}
}
This is a small addition that meaningfully improves accessibility, and the generator can include it in the exported CSS.
Use Cases
- Hero sections — an eye-catching first impression
- Loading screens — visual feedback while data fetches
- Buttons on hover — an interactive accent (see the gradient buttons guide)
- Full-page backgrounds — an immersive feel
- Card borders — subtle animated edges
Build One in Seconds
- Open the gradient generator and switch to animation mode.
- Pick your colors, or start from one of the animated presets.
- Set the speed to match the mood you want.
- Optionally switch to OKLCH for cleaner blends.
- Copy the complete CSS — gradient,
background-size, and@keyframesincluded.
The tool is free, client-side, and free of watermarks, so you can experiment until the motion feels exactly right.
Frequently Asked Questions
Do animated gradients hurt performance?
Not usually. Animating background-position is GPU-composited and lightweight. Keep heavy content off the animating layer and limit full-screen animations per page and you'll be fine.
How do I make the loop seamless?
Return the background-position to its starting value at the 100% keyframe, as in the examples above. That way the animation restarts with no visible jump.
Can I turn off the animation for reduced-motion users?
Yes, and you should. Wrap an animation: none override in a @media (prefers-reduced-motion: reduce) block. The generator can add this for you.
What duration should I use?
For most sites, 10–15 seconds feels alive without being distracting. Go 20–30 seconds for corporate work and 3–5 seconds for high-energy pages.
Ready to animate? Open the free CSS Gradient Generator →