GuideApril 2025 · 10 min read

Animated SVG: SMIL vs CSS vs React

In 2025, there are three battle-tested ways to animate SVG in a browser. This guide breaks down each approach — what it is, when to use it, and what the output code looks like — so you can pick the right tool for every situation.

What is an Animated SVG, Really?

An animated SVG is any SVG where visual properties change over time — position, size, rotation, color, opacity, or path shape. The SVG spec is powerful enough to express all of this natively, but browsers have also layered CSS and JS animation support on top.

The result: three distinct animation stacks, each with different trade-offs around file size, browser support, runtime dependency, and flexibility. Let's look at each one.

Option 1 — SMIL: Native SVG Animation

SMIL (Synchronized Multimedia Integration Language) is SVG's built-in animation system. You add animation tags directly inside the SVG file — no CSS, no JavaScript, no external file.

<svg viewBox="0 0 40 40" xmlns="http://www.w3.org/2000/svg">
  <circle cx="20" cy="20" r="8" fill="#6366f1">
    <animate
      attributeName="r"
      values="8;14;8"
      dur="1.2s"
      repeatCount="indefinite"
      calcMode="spline"
      keyTimes="0;0.5;1"
      keySplines="0.4 0 0.6 1;0.4 0 0.6 1"
    />
  </circle>
</svg>

Pros

  • · Self-contained — one .svg file
  • · Works in <img> tags and emails
  • · Zero JS, zero CSS, zero runtime
  • · Per-keyframe cubic-bezier easing

Cons

  • · Verbose XML syntax
  • · Hard to write by hand
  • · No IE support (not an issue in 2025)
  • · Can't be driven by JS events easily

Best for: standalone icons, SVG sprites, email signatures, any context where you need a single self-contained animated file.

Option 2 — CSS Keyframes: The Web Standard

CSS @keyframes applies animation via stylesheets. The SVG markup stays clean; the motion lives in the CSS file.

/* animation.css */
@keyframes pulse {
  0%, 100% { r: 8px; }
  50%       { r: 14px; }
}

.loader circle {
  animation: pulse 1.2s cubic-bezier(0.4,0,0.6,1) infinite;
  transform-box: fill-box;
}
CSSVG Editor export screen showing CSS keyframes output

Pros

  • · Familiar CSS syntax
  • · Easy to override with class toggles
  • · GPU-accelerated transforms
  • · Works in all modern browsers

Cons

  • · Won't animate inside <img>
  • · Requires separate .css file (or <style>)
  • · No per-keyframe easing (use steps or one timing fn)

Best for: UI components, loading spinners, icon hover effects, any SVG embedded inline in a webpage.

Option 3 — React: Full Component Control

Exporting an animated SVG as a React component gives you the cleanest integration with modern front-end stacks. The SVG is JSX, so you can accept props, wire state, and respond to user interaction.

// AnimatedScene.tsx — drop into Next.js or Vite
export default function AnimatedScene() {
  return (
    <svg viewBox="0 0 40 40" width="100%" height="100%"
         xmlns="http://www.w3.org/2000/svg">
      <g transform="translate(20,20)">
        <circle r="8" fill="#6366f1">
          <animate attributeName="r"
            values="8;14;8" dur="1.2s"
            repeatCount="indefinite"
            calcMode="spline"
            keyTimes="0;0.5;1"
            keySplines="0.4 0 0.6 1;0.4 0 0.6 1" />
        </circle>
      </g>
    </svg>
  );
}

CSSVG's React export uses inline SMIL inside JSX — so you get the self-contained animation behaviour of SMIL with the component ergonomics of React. Works out of the box with Next.js, Vite, and Create React App.

Side-by-Side Comparison

FeatureSMILCSSReact
Browser supportChrome, Firefox, Safari (no IE)All modern browsersWherever React runs
JavaScript requiredNoNoYes (React runtime)
File formatSelf-contained .svg.svg + .css.tsx / .jsx component
Animation on <img> tagYesNoNo
Dynamic control at runtimeLimitedVia class toggleFull (state/props)
Best forStandalone icons, emailWeb pages, UI loadersComponent libraries, Next.js

Which Should You Use?

Use SMIL if…

you need a single .svg file that animates anywhere — in an <img> tag, email, Figma, or README. No build step, no stylesheet, no runtime.

Use CSS if…

you're building a web page and want clean, maintainable stylesheets. Great for loading spinners, hover effects, and UI micro-animations where JS class toggling is enough control.

Use React if…

you're working in a Next.js or Vite codebase and want to pass props, wire state, or conditionally trigger animations based on user interaction.

Export All Three from One Editor

CSSVG exports all three formats from the same animation. Build once on the visual timeline, then choose your output format at export time — SMIL SVG, CSS zip, or React TSX.

CSSVG Editor export screen showing CSS keyframes output

Build Animated SVG Visually

Timeline editor, per-keyframe easing, and three export formats — SMIL, CSS, and React. Free, no sign-up required.

Open the Editor — it's free