SVGs aren't just static images — they're programmable documents that can move, morph, and respond to user interaction. Unlike GIF or video animations, SVG animations are resolution-independent, file-size efficient, and can be controlled with code. Here's how to animate SVGs using three different methods.
CSS is the simplest way to animate SVG elements. Most CSS properties that work on HTML elements also work on SVG elements — with a few SVG-specific additions.
<svg viewBox="0 0 100 100">
<style>
.fade-in { animation: fade 2s ease-in-out infinite alternate; }
@keyframes fade { from { opacity: 0; } to { opacity: 1; } }
</style>
<circle class="fade-in" cx="50" cy="50" r="40" fill="#7c3aed"/>
</svg>
<style>
.spin { animation: spin 3s linear infinite; transform-origin: 50px 50px; }
@keyframes spin { to { transform: rotate(360deg); } }
</style>
What CSS can animate on SVG: opacity, transform (rotate/scale/translate), fill color, stroke color, stroke-width, stroke-dashoffset (for "drawing" effect).
What CSS can't animate: path data (d attribute), points attribute on polygons, complex shape morphing.
Browser support: Excellent (97%+). The most reliable method.
SMIL (Synchronized Multimedia Integration Language) is SVG's built-in animation system. It can animate attributes that CSS can't touch — most importantly, path data for shape morphing.
<svg viewBox="0 0 200 100">
<path fill="#7c3aed">
<animate attributeName="d"
values="M50,50 A30,30 0 1,1 110,50 A30,30 0 1,1 50,50;
M40,20 L160,20 L160,80 L40,80 Z;
M50,50 A30,30 0 1,1 110,50 A30,30 0 1,1 50,50"
dur="3s" repeatCount="indefinite"/>
</path>
</svg>
<line x1="10" y1="50" x2="190" y2="50" stroke="#7c3aed" stroke-width="4"> <animate attributeName="stroke-dashoffset" from="180" to="0" dur="2s" fill="freeze"/> </line>
Pros: Animates path data, works without JavaScript, declarative syntax. Cons: Chrome once tried to deprecate it (reversed), IE never supported it, slightly less performant than CSS for many simultaneous animations.
For complex, interactive, or data-driven animations, JavaScript libraries provide the most power and control.
gsap.to(".my-circle", {
duration: 2,
attr: { r: 80, fill: "#f59e0b" },
repeat: -1,
yoyo: true,
ease: "power2.inOut"
});
anime({
targets: ".line-segment",
strokeDashoffset: [anime.setDashoffset, 0],
duration: 2000,
delay: anime.stagger(200),
easing: "easeInOutSine"
});
When to use JS: Dynamic animations based on user input, complex timelines with many staggered elements, physics-based motion, integration with data (chart transitions).
| Feature | CSS | SMIL | JS |
|---|---|---|---|
| Ease of use | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐ |
| Path morphing | ❌ | ✅ | ✅ |
| Performance | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐ |
| Browser support | 97%+ | ~95% | 100% |
| Best for | Simple UI animations | Shape morphing | Complex interactive |
will-change: transform on animated elements to promote them to GPU layertransform and opacity — these are GPU-acceleratedfilter — it's CPU-intensive and can cause jankIf you've created an animated SVG and need to share it where SVG isn't supported (social media, email), you'll need to convert it. Use a screen recorder or a tool like FFmpeg to capture the animation as MP4 or GIF. For static snapshots at a specific point in the animation, convert the SVG to PNG with svg2png.org.