Gradients guide

Motion

Animated CSS Gradient Backgrounds

An animated gradient is a still gradient plus one cheap trick: oversize the background, then animate its position. The paint work stays a single compositable layer, so the drift costs almost nothing — which is exactly why restraint, not capability, is the constraint. Ambient motion should be slow enough to deny.

Glacial by default
Ambient drift belongs at 10–20s per cycle; anything faster is a notification.
Animate position, not stops
Moving background-position composites cheaply; repainting gradient stops every frame does not.
Honor reduced motion
Every animated surface needs a prefers-reduced-motion rule that parks it on a good still frame.

Gradient examples

4 effects built from CSS alone

Every swatch below is painted by the declaration beside it — no image files. The stops come from color-mix over your theme tokens, so switch modes and watch each sample follow.

01

Ambient pan

Oversize a soft diagonal ramp and let it drift back and forth — the living-surface effect behind sign-in pages and hero sections.

The background must be larger than the element (200%+ each axis) or the pan has nowhere to go and the surface just sits there.

.ambient-pan {
  background-image: linear-gradient(115deg,
    color-mix(in oklab, var(--primary) 14%, transparent),
    transparent 45%,
    color-mix(in oklab, var(--primary) 10%, transparent) 85%);
  background-size: 250% 250%;
  animation: pan 14s ease-in-out infinite alternate;
}
@keyframes pan {
  from { background-position: 0% 50%; }
  to   { background-position: 100% 50%; }
}
02

Aurora drift

Give the aurora veil an oversized canvas and a slow pan, so the sheets of light migrate across the header over half a minute.

Slower is stronger here — at 20s+ the movement is only visible to someone who lingers, which is the point.

.aurora-drift {
  background-image:
    radial-gradient(60% 35% at 20% 10%,
      color-mix(in oklab, var(--primary) 14%, transparent), transparent 70%),
    radial-gradient(55% 30% at 80% 25%,
      color-mix(in oklab, var(--primary) 10%, transparent), transparent 70%);
  background-size: 180% 180%;
  animation: pan 22s ease-in-out infinite alternate;
}
03

Skeleton shimmer

Sweep a faint highlight across a placeholder in one direction — the loading shimmer, the only animated gradient with a job to do.

Sweep one way and loop; the alternate direction reads as a scrubber. Keep the highlight neutral, not brand-colored.

.shimmer {
  background-color: var(--muted);
  background-image: linear-gradient(90deg,
    transparent,
    color-mix(in oklab, var(--foreground) 6%, transparent),
    transparent);
  background-size: 200% 100%;
  animation: sweep 1.6s linear infinite;
}
@keyframes sweep {
  from { background-position: 200% 0; }
  to   { background-position: -200% 0; }
}
04

Hue drift

Rotate the hue of a mesh through the color wheel — the loudest effect in this guide, for launch pages and little else.

filter: hue-rotate repaints the layer every frame and cycles through hues your palette never approved — fence it to one small, text-free surface.

.hue-drift {
  background-image:
    radial-gradient(circle at 25% 20%,
      color-mix(in oklab, var(--primary) 20%, transparent), transparent 50%),
    radial-gradient(circle at 75% 80%,
      color-mix(in oklab, var(--primary) 14%, transparent), transparent 50%);
  animation: hue 18s linear infinite;
}
@keyframes hue {
  to { filter: hue-rotate(360deg); }
}

Implementation check

Ship the still, solid version everywhere else.

Judge the gradient with real content on top, in both modes, and measure text contrast against the strongest stop it sits on — not the base surface alone. Then park animated surfaces on a still frame for reduced motion, and give clipped text a solid color for forced-color modes.

@media (prefers-reduced-motion: reduce) {
  .animated-gradient { animation: none; }
}

@media (forced-colors: active) {
  .gradient-headline {
    background-image: none;
    color: CanvasText;
  }
}

Carry the light into a complete theme.

Nodlume's theme defines the palette, fonts, shadows, and textures these gradients are mixed from, and generates them into the React project with everything else.

Start planning free

We'd like to use Google cookies to understand how Nodlume is used and to measure our advertising. Nothing loads until you choose, and declining does not affect anything in the app.