#135: Three Ways to Animate SVG

Avatar of Chris Coyier
Chris Coyier on (Updated on )

📣 Freelancers, Developers, and Part-Time Agency Owners: Kickstart Your Own Digital Agency with UACADEMY Launch by UGURUS 📣

Animating SVG is a bit unique in that there are three distinctly different ways you can approach animating it.

1. Animating with CSS @keyframes

SVG elements can be targeted and styled with CSS. Meaning, you can apply animation through @keyframes. Like this:

<svg viewBox="0 0 127.9 178.4">
  <path id="left-leg" d="M37.6,138.8c0 ... " />
</svg>
.left-leg {
  fill: orange;
  animation: dance 2s infinite alternate;
}
@keyframes dance {
  100% {
    transform: rotate(3deg);
  }
}

You might choose animating this way if…

  • The animation is fairly simple.
  • You only need to animate properties that CSS can animate.
  • You already know and are comfortable with CSS animations.

2. Animating with SMIL

There is a syntax for animations built right into SVG. Here’s a very simple example:

<svg viewBox="0 0 127.9 178.4">
  <path d="M37.6,138.8c0 ... ">
    <animate attributeName="fill" dur="5000ms" to="#f06d06" fill="freeze" />  
  </path>
</svg>

Here’s a big tutorial on all that is SMIL.

You might choose animating this way if…

  • You need to animate properties that CSS can’t, like the shape itself.
  • You need other SMIL specific features, like beginning an animation when another ends without manually syncing durations/delays. Or interaction stuff, like beginning an animation on a click.

3. Animating with JavaScript

With JavaScript, you have access to things like requestAnimationFrame (or other loops), so you can animate just by way of rapidly changing property values. There are also frameworks out there for working with SVG that typically have animation stuff built in. Or animation frameworks that work with SVG. Like SnapSVG, GreenSock, SVG.js, or Velocity.js.

Here’s an example with SnapSVG:

<svg id="robot" viewBox="0 0 127.9 178.4">
  <circle id="left-pupil" cx="34.4" cy="15.4" r="4.8" />
</svg>
var s = Snap("#robot");
var leftPupil = s.select("#left-pupil");

leftPupil.animate({
  r: 50,
  fill: "lightgreen"
}, 1000);

You might choose animating this way if…

  • You’re working in JavaScript anyway, perhaps your animation has to do with data you receive with JSON or the like.
  • You need JavaScript anyway, because you need the logic or math or something else really only possible there.
  • You’re interested in the JavaScript solving some bugs for you.
  • The scope of your animation is rather large/complicated and you need the abstraction and organization JavaScript can provide.

Demo

See the Pen Three Ways to Animate SVG by Chris Coyier (@chriscoyier) on CodePen.

Doesn’t how you ultimately use the SVG affect your options?

It does. If you’re using SVG-as-<img>, you won’t be able to use use CSS animations from another stylesheet. But, you’re SMIL animations will work, in some browsers (at the time of this writing, Chrome yes, Firefox no). I wouldn’t be surprised if embedded CSS in SVG files work or will work one day. JavaScript, probably not.

If you’re using SVG in a CSS background-image, I imagine it’s a similar story as above.

If you use inline <svg>, all the possibilities are open to you.

If you’re using SVG through an object or iframe, you would need to embed the scripts/styles right in the SVG for it to work.