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>
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; }
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 });
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; }
}
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 */
}
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
transformover attribute changes - Use
will-change: transformto 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)