Animation

Animating SVG Backgrounds with CSS & SMIL

From subtle breathing patterns to dramatic morphing tiles — learn every technique for animating SVG background patterns.

10 min read Jan 2026 3 PDF downloads

The Two Animation Systems

SVG animations can use CSS (keyframes, transitions, and the Web Animations API) or SMIL (SVG's built-in animation elements: <animate>, <animateTransform>, <animateMotion>). CSS is more widely understood and easier to debug. SMIL is more powerful for path-following and transform animations, but is deprecated in Chrome (though not removed).

Animating background-position (Scroll Effect)

The cheapest SVG animation is shifting background-position with CSS. This moves the pattern tile offset, creating an infinite scroll or drift effect. The animation runs entirely on the compositor thread — no layout, no paint — making it silky smooth even on low-end devices.

@keyframes drift {
  from { background-position: 0 0; }
  to   { background-position: 40px 40px; }
}
.animated-pattern {
  animation: drift 8s linear infinite;
  background-image: url('data:image/svg+xml;base64,...');
}

Animating background-size (Pulse/Breathe)

Animating background-size scales the tile, creating a breathing or pulsing effect. Use ease-in-out for an organic feel. Combine with background-position: center to keep the pattern centred as it scales. Keep the scale range modest (±10–20%) to avoid dizzying visual effects.

CSS Variables in SVG Data URIs

CSS custom properties (variables) do not work inside data URI SVGs because the SVG content is not part of the CSS cascade. To dynamically change pattern colours, use inline <svg> elements as backgrounds (via a positioned pseudo-element) where CSS variables do apply, or update the data URI via JavaScript when variables change.

SMIL animateTransform on pattern

Inside an SVG <pattern>, you can animate the patternTransform attribute using <animate>. This rotates or translates the entire tile grid. A slowly rotating grid creates a hypnotic optical effect with no JavaScript needed.

<pattern id="rotating">
  <animateTransform attributeName="patternTransform"
    type="rotate" from="0" to="360"
    dur="20s" repeatCount="indefinite"/>
  <circle cx="10" cy="10" r="3" fill="#6366f1"/>
</pattern>

Respecting prefers-reduced-motion

Always wrap animations in a @media (prefers-reduced-motion: no-preference) query. Users who have enabled reduced motion in their OS settings — including many people with vestibular disorders — should never see auto-playing animations. Static versions of all animated patterns must work perfectly.

JavaScript-Driven Animations (WAAPI)

The Web Animations API (element.animate()) gives JavaScript control with CSS-level compositor performance. Use it to sync pattern animations with scroll position, cursor position, or data values. Combine with requestAnimationFrame for smooth 60fps interactions — update a CSS custom property that controls the pattern's scale or position.