DEV Community

Michael Lip
Michael Lip

Posted on • Originally published at zovo.one

Animating SVGs Without a Library: What Actually Works

Every time I reach for an animation library to animate an SVG, I remind myself that SVG has built-in animation capabilities that are more performant, more precise, and require zero dependencies. The problem is that SVG animation is poorly documented and full of gotchas.

The three animation approaches

SVG supports three distinct animation methods, each with different strengths.

SMIL (Synchronized Multimedia Integration Language). Native SVG animation elements like <animate>, <animateTransform>, and <animateMotion>. These live inside the SVG markup and run without JavaScript. Chrome deprecated SMIL in 2015, then reversed the deprecation. It works in all modern browsers today.

<circle cx="50" cy="50" r="20" fill="#6C5CE7">
  <animate attributeName="r" values="20;30;20" dur="2s" repeatCount="indefinite"/>
</circle>
Enter fullscreen mode Exit fullscreen mode

CSS animations. Standard @keyframes applied to SVG elements. Works well for transforms, opacity, and color changes. The SVG must be inline (not referenced via <img>), and some properties (like path d attribute) cannot be animated with CSS.

@keyframes pulse {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.2); }
}
circle { animation: pulse 2s infinite; }
Enter fullscreen mode Exit fullscreen mode

JavaScript (Web Animations API or requestAnimationFrame). The most flexible option. Can animate any attribute, including path data. Required for complex sequenced animations and interactive animations.

element.animate([
  { transform: 'translateX(0)' },
  { transform: 'translateX(200px)' }
], { duration: 1000, iterations: Infinity });
Enter fullscreen mode Exit fullscreen mode

Path animation: the showpiece effect

The most visually striking SVG animation is the "drawing" effect, where a path appears to draw itself. This uses the stroke-dasharray and stroke-dashoffset properties.

The concept: set the dash length equal to the total path length. Set the offset equal to the path length (hiding the entire dash). Animate the offset to 0, and the path appears to draw itself.

.draw-path {
  stroke-dasharray: 1000;
  stroke-dashoffset: 1000;
  animation: draw 3s ease forwards;
}
@keyframes draw {
  to { stroke-dashoffset: 0; }
}
Enter fullscreen mode Exit fullscreen mode

To get the exact path length, use path.getTotalLength() in JavaScript. Hardcoding a number that does not match the actual path length will either clip the animation or leave a visible gap.

Transform-origin headaches

The single most frustrating aspect of SVG animation is transform-origin. In HTML, transforms default to the center of the element. In SVG, transforms default to the origin of the SVG coordinate system (0,0).

This means rotating a rectangle at (100, 100) will swing it around the top-left corner of the SVG, not around its own center. You need to explicitly set the transform origin.

rect {
  transform-origin: 120px 120px; /* center of the rect */
  transform-box: fill-box; /* or use this */
}
Enter fullscreen mode Exit fullscreen mode

transform-box: fill-box tells the browser to use the element's bounding box as the reference, making transforms behave like HTML elements. This single property fixes 90% of SVG transform frustrations.

Performance considerations

SVG animations can be GPU-accelerated if they animate transforms and opacity. Animating cx, cy, r, width, height, or d triggers layout recalculations and is not GPU-accelerated.

For smooth 60fps animation:

  • Prefer transform over attribute changes
  • Use will-change: transform to hint the browser
  • Avoid animating filters (especially feGaussianBlur) -- they are extremely expensive
  • Keep the number of animated elements reasonable. 50 simultaneously animated SVG elements will cause frame drops on mobile

Building animations visually

Writing SVG animation code by hand is tedious. Adjusting timing curves, durations, and sequences through code-edit-refresh cycles is slow. I built an SVG animator at zovo.one/free-tools/svg-animator that provides a visual timeline editor for SVG animations. Import your SVG, add keyframes visually, adjust easing curves, and export the animated SVG with the animation baked in (SMIL or CSS, your choice).

The fastest way to learn SVG animation is to see the results in real time as you adjust parameters. The feedback loop makes the difference.

I'm Michael Lip. I build free developer tools at zovo.one. 500+ tools, all private, all free.

Top comments (0)