SolutionsCase StudiesAI ToolsResourcesAboutContact
Get Your Free AI Automation Audit Book a Free 30-Minute Strategy Call
Playground~/frontend Open editor

~/css/gradient-animations

7 CSS Gradient Animations

7 Pure CSSPublished 2026-10-05Free · no sign-up

Seven ways to animate gradients: an angle that turns, colour stops that morph, a mesh whose centres drift, stripes moving along a progress bar, a hue rotation, a gradient border that flows round a card and a metallic sheen across a word.

01. Rotating Linear Gradient

Gradient@property

A linear gradient whose angle turns slowly through 360 degrees. Without @property the browser cannot interpolate the angle inside a gradient, so the angle is registered as an <angle> custom property and that property is animated.

View code
<div class="ga1"><p>Live preview</p></div>
@property --ga1 { syntax: "<angle>"; initial-value: 0deg; inherits: false; }
.ga1 { display: grid; place-items: center; width: 260px; max-width: 100%; height: 160px; border-radius: 18px; background: linear-gradient(var(--ga1), #4f46e5, #db2777, #f59e0b); animation: ga1 6s linear infinite; font: 800 22px Inter, system-ui, sans-serif; }
.ga1 p { margin: 0; padding: 8px 14px; border-radius: 10px; background: rgba(2,6,23,.6); color: #fff; }
@keyframes ga1 { to { --ga1: 360deg; } }
@media (prefers-reduced-motion: reduce) { .ga1 { animation: none; } }

02. Animating Colour Stops

Gradient@property

Two registered colour properties feed a gradient, and animating them makes the colours themselves change, not just their position. This is the only way to smoothly morph a gradient's colours in CSS.

View code
<div class="ga2" role="img" aria-label="Gradient changing from teal and blue to orange and pink"></div>
@property --ga2a { syntax: "<color>"; initial-value: #14b8a6; inherits: false; }
@property --ga2b { syntax: "<color>"; initial-value: #3b82f6; inherits: false; }
.ga2 { width: 260px; max-width: 100%; height: 160px; border-radius: 18px; background: linear-gradient(135deg, var(--ga2a), var(--ga2b)); animation: ga2 5s ease-in-out infinite alternate; }
@keyframes ga2 { to { --ga2a: #f97316; --ga2b: #db2777; } }
@media (prefers-reduced-motion: reduce) { .ga2 { animation: none; } }

03. Drifting Mesh Gradient

GradientMesh

Three radial gradients whose centres drift on slightly different loops, a living mesh behind a hero. The centre coordinates are registered percentage properties, so each one interpolates smoothly while the others move on their own timings.

View code
<div class="ga3"><h3>Signals</h3></div>
@property --ga3x { syntax: "<percentage>"; initial-value: 20%; inherits: false; }
@property --ga3y { syntax: "<percentage>"; initial-value: 30%; inherits: false; }
.ga3 { display: grid; place-items: center; width: 260px; max-width: 100%; height: 170px; border-radius: 18px; background: radial-gradient(circle at var(--ga3x) var(--ga3y), #a855f7, transparent 50%), radial-gradient(circle at calc(100% - var(--ga3x)) 70%, #06b6d4, transparent 55%), radial-gradient(circle at 50% calc(100% - var(--ga3y)), #f43f5e, transparent 50%), #0b1020; animation: ga3 9s ease-in-out infinite alternate; }
.ga3 h3 { margin: 0; color: #fff; font: 800 26px Inter, system-ui, sans-serif; }
@keyframes ga3 { to { --ga3x: 70%; --ga3y: 80%; } }
@media (prefers-reduced-motion: reduce) { .ga3 { animation: none; } }

04. Moving Striped Progress

GradientProgress

Diagonal stripes travel along a progress bar to show work is ongoing. The stripes are a repeating linear gradient whose background-position moves by exactly one stripe period, so the loop is seamless. The bar is a labelled progressbar with its value.

View code
<div class="ga4"><p id="ga4l">Uploading 3 of 5 files</p><div class="bar" role="progressbar" aria-labelledby="ga4l" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100"><span style="width:60%"></span></div></div>
.ga4 { width: 280px; max-width: 100%; font-family: Inter, system-ui, sans-serif; }
.ga4 p { margin: 0 0 6px; color: #344054; font-size: 13px; font-weight: 600; }
.ga4 .bar { height: 14px; border-radius: 7px; background: #eaecf0; overflow: hidden; }
.ga4 span { display: block; height: 100%; border-radius: 7px; background: repeating-linear-gradient(45deg, #2563eb 0 10px, #3b82f6 10px 20px); background-size: 28.28px 100%; animation: ga4 .8s linear infinite; }
@keyframes ga4 { to { background-position: 28.28px 0; } }
@media (prefers-reduced-motion: reduce) { .ga4 span { animation: none; } }

05. Hue Rotate Cycle

GradientFilter

The simplest colour cycle: one gradient and filter: hue-rotate animating from 0 to 360 degrees, which shifts every colour around the wheel together. It also affects any content inside, so keep text outside the filtered layer, as here.

View code
<div class="ga5"><span class="bg" aria-hidden="true"></span><p>Prism</p></div>
.ga5 { position: relative; display: grid; place-items: center; width: 260px; max-width: 100%; height: 160px; border-radius: 18px; overflow: hidden; }
.ga5 .bg { position: absolute; inset: 0; background: linear-gradient(135deg, #f43f5e, #f59e0b, #22c55e); animation: ga5 8s linear infinite; }
.ga5 p { position: relative; margin: 0; padding: 8px 14px; border-radius: 10px; background: rgba(2,6,23,.65); color: #fff; font: 800 22px Inter, system-ui, sans-serif; }
@keyframes ga5 { to { filter: hue-rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .ga5 .bg { animation: none; } }

06. Flowing Gradient Border

GradientBorder

A card whose border is a gradient flowing round it, done with two backgrounds: the card colour clipped to the padding box and an oversized gradient clipped to the border box, moved with background-position.

View code
<article class="ga6"><h3>Pro</h3><p>All features, priority help.</p></article>
.ga6 { width: 230px; max-width: 100%; box-sizing: border-box; padding: 20px; border: 2px solid transparent; border-radius: 16px; background: linear-gradient(#111527, #111527) padding-box, linear-gradient(90deg, #22d3ee, #a855f7, #f43f5e, #22d3ee) 0 0 / 300% 100% border-box; color: #cbd5e1; font-family: Inter, system-ui, sans-serif; animation: ga6 4s linear infinite; }
.ga6 h3 { margin: 0 0 4px; color: #fff; } .ga6 p { margin: 0; font-size: 14px; }
@keyframes ga6 { to { background-position: 0 0, 300% 0; } }
@media (prefers-reduced-motion: reduce) { .ga6 { animation: none; } }

07. Gradient Sheen on Text

GradientText

A metallic sheen sweeps across a word every few seconds: a gradient clipped to the text, mostly one colour with a bright band, moving with background-position. Outside the sweep it rests on solid dark text that is easy to read.

View code
<p class="ga7">Premium</p>
.ga7 { margin: 0; color: #1f2937; font: 900 54px Inter, system-ui, sans-serif; }
@supports ((-webkit-background-clip: text) or (background-clip: text)) {
  .ga7 { background: linear-gradient(110deg, #1f2937 40%, #9ca3af 50%, #1f2937 60%) 100% 0 / 250% 100%; -webkit-background-clip: text; background-clip: text; color: transparent; animation: ga7 3.5s ease-in-out infinite; }
}
@keyframes ga7 { 0%, 30% { background-position: 100% 0; } 70%, 100% { background-position: 0 0; } }
@media (prefers-reduced-motion: reduce) { .ga7 { animation: none; } }

About these CSS Gradient Animations

Why gradients do not animate

A gradient is an image, and browsers cannot interpolate one image into another. Change something they can interpolate instead: the background position, a filter, or a registered custom property used inside the gradient.

@property unlocks gradients

Register an angle, colour or percentage with @property and give it a syntax. The browser can then animate the property, and the gradient that uses it updates on every frame.

Seamless loops

For moving stripes or patterns, move the background by exactly one repeat of the pattern so the end frame matches the start. For diagonal stripes that repeat is the stripe period divided by the sine of the angle.

Keep text off the moving layer

Effects like hue-rotate apply to everything inside the element. Put the animated gradient on its own layer and the text above it on a solid backing for contrast.

Frequently asked questions

Which browsers support @property?

All current major browsers. Older ones show the gradient without animating it.

Are animated gradients heavy?

Repainting a large gradient every frame costs more than moving it. Keep animated areas modest.

Can I animate a gradient border?

Yes, with two backgrounds, one clipped to the padding box and one to the border box, as the border demo shows.