TutorialApril 2025 · 8 min read

How to Create Animated SVG with CSS Keyframes

A complete 2025 guide to creating animated SVG using CSS @keyframes — no JavaScript, no Lottie, no GSAP. Pure browser-native animation that ships zero runtime bytes.

What is an Animated SVG?

An animated SVG is a Scalable Vector Graphic file that contains motion — elements that move, fade, scale, rotate, or morph over time. Unlike GIF or video, animated SVG stays sharp at any resolution because the shapes are mathematical, not pixel-based.

There are three main ways to drive SVG animation in a browser: CSS keyframes, SMIL (native SVG animation tags), and JavaScript libraries like GSAP or Anime.js. This guide focuses on CSS keyframes — the most compatible, easiest to maintain, and zero-runtime option.

Why Use CSS Keyframes for SVG Animation?

  • No JavaScript: Pure CSS runs in the browser without any JS payload. Your Core Web Vitals score stays clean.
  • Full browser support: CSS @keyframes works in Chrome, Firefox, Safari, and Edge — including mobile browsers.
  • Easy to maintain: One @keyframes block reads like a timeline. No callback chains, no tweening library APIs.
  • Composable: Combine multiple @keyframes on one element using animation shorthand with comma-separated values.
  • GPU accelerated: Animating transform and opacity triggers compositor-layer promotion — smooth 60fps with no layout thrash.

CSS @keyframes Syntax for SVG

The CSS @keyframes rule defines a named animation sequence. You then apply it to any SVG element using the animation property. Here is the basic structure:

@keyframes fadeIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* Apply to an SVG circle */
circle {
  animation: fadeIn 0.6s ease-out forwards;
}

You can use percentage stops for fine-grained control:

@keyframes bounce {
  0%   { transform: translateY(0); }
  40%  { transform: translateY(-12px); }
  70%  { transform: translateY(-6px); }
  100% { transform: translateY(0); }
}

rect {
  animation: bounce 1s cubic-bezier(0.34, 1.56, 0.64, 1) infinite;
}

Animating SVG Transforms

The most common properties to animate on SVG elements are transform (translate, rotate, scale) and opacity. Both are GPU-composited and won't trigger layout recalculation.

CSSVG Editor export screen showing CSS keyframes output
@keyframes spinAndFade {
  0%   { transform: rotate(0deg);   opacity: 0; }
  50%  { transform: rotate(180deg); opacity: 1; }
  100% { transform: rotate(360deg); opacity: 0; }
}

.my-icon path {
  animation: spinAndFade 2s ease-in-out infinite;
  transform-origin: center;
  transform-box: fill-box; /* critical for SVG */
}

Important: Always add transform-box: fill-box when animating SVG transforms. Without it, the transform origin defaults to the SVG viewport, not the element's own bounding box — causing unexpected rotation and scale behaviour.

Stroke Drawing Effect with stroke-dasharray

One of the most popular animated SVG tricks is the “draw-on” stroke effect. It works by setting stroke-dasharray to the total path length, then animating stroke-dashoffset from that length down to zero.

/* Get path length with JS: path.getTotalLength() */
/* e.g. 340px */

path {
  stroke-dasharray: 340;
  stroke-dashoffset: 340;
  animation: draw 1.5s ease forwards;
}

@keyframes draw {
  to { stroke-dashoffset: 0; }
}

Combining Multiple Animations

CSS lets you stack animations on a single element by comma-separating them. Each can have its own duration, easing, and delay — giving you full keyframe-level control:

circle {
  animation:
    pulse  1.2s ease-in-out infinite,
    colorShift 3s linear infinite;
}

@keyframes pulse {
  0%, 100% { r: 8; }
  50%       { r: 12; }
}

@keyframes colorShift {
  0%   { fill: #6366f1; }
  50%  { fill: #ec4899; }
  100% { fill: #6366f1; }
}

Export Animated SVG CSS from CSSVG Editor

Writing CSS keyframes by hand works, but for complex multi-element animations with per-keyframe easing, a visual editor saves hours. CSSVG lets you build animations on a timeline — drag shapes, set keyframes, adjust easing curves — then export clean CSS @keyframes with one click.

CSSVG Editor export screen showing CSS keyframes output

The exported .zip contains an index.html, an animation.svg, and an animation.css — all production-ready. Open index.html directly in any browser.

Performance Tips for Animated SVG

  • Animate transform and opacity only: These two properties trigger GPU compositing. Animating width, height, or fill triggers layout/paint and will cause jank at scale.
  • Use will-change sparingly: Add will-change: transform to elements with heavy animations. Don't apply it globally — each layer consumes GPU memory.
  • Add transform-box: fill-box: Always set this on SVG elements so transform-origin is relative to the element, not the viewport.
  • Prefer animation-fill-mode: forwards: For one-shot animations, use forwards so the element holds its final state without needing JS to clean up.
  • Reduce motion: Wrap your animations in @media (prefers-reduced-motion: no-preference) to respect accessibility settings.

Try it in the CSSVG Editor

Build animated SVGs visually on a timeline. Export clean CSS keyframes, pure SMIL SVG, or a React component — all for free.

Open the Editor — it's free