Introduction to SVG animations
The SVG (Scalable Vector Graphics) format offers unmatched animation possibilities compared to bitmap images. Thanks to its vector nature and DOM integration, every element of an SVG can be animated individually with surgical precision.
In this complete guide, we will explore 6 essential SVG animation techniques, from the famous "line draw" effect to advanced shape morphing. Each technique comes with interactive examples and ready-to-use code.
SVG animations are lightweight (a few KB), infinitely scalable, and never lose quality. They are ideal for icons, logos, illustrations and data visualizations.
SVG animations can be achieved in three ways:
- CSS Animations/Transitions: The simplest and most performant method
- SMIL (Synchronized Multimedia Integration Language): Native SVG animations, powerful but deprecated in some browsers
- JavaScript: For complex and interactive animations (GSAP, anime.js, etc.)
1. Stroke animation (line draw effect)
The "line draw" effect is probably the most popular SVG animation. It gives the impression that the drawing is being traced before your eyes, as if someone is drawing it in real time.
This technique relies on two magical CSS properties: stroke-dasharray and stroke-dashoffset.
/* The magic of line draw */
.svg-line-draw path,
.svg-line-draw circle,
.svg-line-draw rect {
/* Sets the stroke and gap length */
stroke-dasharray: 1000;
/* Offsets the stroke (hides it) */
stroke-dashoffset: 1000;
/* Animation that reveals the stroke */
animation: lineDraw 2s ease forwards;
}
@keyframes lineDraw {
to {
stroke-dashoffset: 0;
}
}
Calculating the exact path length
For a perfect animation, you need to know the exact length of your path. Use JavaScript to get it:
// Select your SVG element
const path = document.querySelector('svg path');
// Get the total length
const length = path.getTotalLength();
console.log('Path length:', length);
// Apply this value
path.style.strokeDasharray = length;
path.style.strokeDashoffset = length;
Use a deliberately high value (like 1000) for stroke-dasharray if you don't want to calculate the exact length. It works as long as the value is greater than the actual path length.
2. SVG path morphing
Morphing allows smoothly transforming one shape into another. It is an impressive technique for icon transitions (hamburger to cross, play to pause, etc.).
For morphing to work, both paths must have the same number of points. This is the main constraint of this technique.
/* CSS transition on the d attribute */
.svg-morph path {
transition: d 0.4s cubic-bezier(0.4, 0, 0.2, 1);
}
/* Initial state: triangle (play) */
.svg-morph.play path {
d: path("M30 20 L30 80 L80 50 Z");
}
/* Morphed state: two bars (pause) */
.svg-morph.pause path {
d: path("M25 20 L25 80 L40 80 L40 20 M60 20 L60 80 L75 80 L75 20");
}
// Toggle between play and pause
function togglePlayPause(svg) {
const path = svg.querySelector('path');
const isPlay = svg.dataset.state !== 'pause';
if (isPlay) {
// Morph to pause (2 bars)
path.setAttribute('d', 'M25 20 L25 80 L40 80 L40 20 Z M60 20 L60 80 L75 80 L75 20 Z');
svg.dataset.state = 'pause';
} else {
// Morph to play (triangle)
path.setAttribute('d', 'M30 20 L30 80 L80 50 Z');
svg.dataset.state = 'play';
}
}
Animating the d property in pure CSS only works in modern browsers (Chrome, Firefox, Safari 15.4+). For maximum compatibility, use a library like GSAP MorphSVG or flubber.
3. CSS animations on SVG
SVG elements accept most animatable CSS properties: transform, opacity, fill, stroke, and many more. Here are the most useful animations.
Continuous rotation
.svg-rotate {
animation: rotate 2s linear infinite;
transform-origin: center;
}
@keyframes rotate {
to {
transform: rotate(360deg);
}
}
/* Variant with steps for staggered effect */
.svg-rotate-steps {
animation: rotate 1s steps(8) infinite;
}
Pulse and Bounce
/* Pulse effect - ideal for notifications */
.svg-pulse {
animation: pulse 1.5s ease-in-out infinite;
}
@keyframes pulse {
0%, 100% {
transform: scale(1);
opacity: 1;
}
50% {
transform: scale(1.15);
opacity: 0.8;
}
}
/* Bounce effect - draws attention */
.svg-bounce {
animation: bounce 1s ease infinite;
}
@keyframes bounce {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-10px); }
}
/* Shake effect - urgent alerts */
.svg-shake {
animation: shake 0.5s ease-in-out infinite;
}
@keyframes shake {
0%, 100% { transform: translateX(0) rotate(0); }
25% { transform: translateX(-3px) rotate(-5deg); }
75% { transform: translateX(3px) rotate(5deg); }
}
Color animation
/* Stroke color animation */
.svg-stroke-color path {
animation: strokeColor 3s ease infinite;
}
@keyframes strokeColor {
0%, 100% { stroke: #6366f1; }
33% { stroke: #8b5cf6; }
66% { stroke: #d946ef; }
}
/* Fill animation */
.svg-fill-fade {
animation: fillFade 2s ease infinite;
}
@keyframes fillFade {
0%, 100% { fill: #6366f1; }
50% { fill: #8b5cf6; }
}
4. SMIL animations (animate, animateTransform)
SMIL (Synchronized Multimedia Integration Language) allows defining animations directly in SVG, without CSS or JavaScript. Although deprecated by Chrome for a time, it is now supported by all modern browsers.
<!-- Simple attribute animation -->
<circle cx="50" cy="50" r="40" fill="#6366f1">
<animate
attributeName="r"
values="30;40;30"
dur="2s"
repeatCount="indefinite"
/>
</circle>
<!-- Transform animation -->
<rect x="30" y="30" width="40" height="40" fill="#8b5cf6">
<animateTransform
attributeName="transform"
type="rotate"
from="0 50 50"
to="360 50 50"
dur="3s"
repeatCount="indefinite"
/>
</rect>
<!-- Animation with custom easing -->
<circle cx="20" cy="50" r="10" fill="#d946ef">
<animate
attributeName="cx"
values="20;80;20"
dur="2s"
repeatCount="indefinite"
calcMode="spline"
keySplines="0.4 0 0.2 1; 0.4 0 0.2 1"
/>
</circle>
SMIL animations work even when SVG is used as <img> or as background-image, unlike CSS which only applies to inline SVGs.
5. Practical animated icons
Here is a collection of ready-to-use animated icons for your projects. These animations are optimized for micro-interactions and user feedback.
Loading icon
Status icons
<svg width="60" height="60" viewBox="0 0 50 50" fill="none">
<!-- Circle being drawn -->
<circle cx="25" cy="25" r="20" stroke="#10b981" stroke-width="3">
<animate
attributeName="stroke-dasharray"
values="0 126;126 126"
dur="0.5s"
fill="freeze"
/>
</circle>
<!-- Checkmark drawn after -->
<path d="M15 25 L22 32 L35 18"
stroke="#10b981"
stroke-width="3"
stroke-linecap="round"
stroke-linejoin="round">
<animate
attributeName="stroke-dasharray"
values="0 30;30 30"
dur="0.3s"
begin="0.5s"
fill="freeze"
/>
</path>
</svg>
6. Performance and accessibility
SVG animations are generally performant, but a few precautions are needed to ensure an optimal experience for all your users.
Performance optimization
- Prefer transform and opacity: These properties benefit from GPU acceleration
- Avoid animating filters: SVG
filtereffects are resource-intensive - Limit the number of simultaneous animations: Beyond 10, performance can drop
- Use will-change sparingly: Reserve it for elements that are truly animated
/* Preparation for animation */
.svg-animated {
will-change: transform;
contain: layout style;
}
/* Force GPU rendering */
.svg-gpu {
transform: translateZ(0);
}
Accessibility
Animations can be problematic for motion-sensitive users. Always respect their system preference:
/* Respect user preference */
@media (prefers-reduced-motion: reduce) {
svg * {
animation: none !important;
transition: none !important;
}
/* Show final state for line draw */
.svg-line-draw path,
.svg-line-draw circle {
stroke-dashoffset: 0;
}
}
SMIL animations (embedded in the SVG) are not affected by prefers-reduced-motion. To disable them, you will need to use JavaScript to remove or modify the <animate> elements.
Alternative text for SVG
<!-- Accessible SVG with role and title -->
<svg role="img" aria-labelledby="icon-title icon-desc">
<title id="icon-title">Loading</title>
<desc id="icon-desc">Circular loading animation</desc>
<!-- SVG content -->
</svg>
<!-- Decorative SVG (ignored by screen readers) -->
<svg aria-hidden="true" focusable="false">
<!-- Decorative SVG content -->
</svg>
Conclusion
SVG animations offer endless possibilities for enriching your interfaces. From the simple line draw effect to complex morphings, you now have a complete arsenal of techniques.
Key takeaways:
- Line draw: Use
stroke-dasharrayandstroke-dashoffsetfor the drawing effect - Morphing: Make sure your paths have the same number of points
- CSS vs SMIL: CSS is simpler, SMIL works everywhere (even as img)
- Performance: Prefer transform and opacity
- Accessibility: Always respect
prefers-reduced-motion
Find over 50 animated SVG icons and illustrations ready to use in our effects library, with one-click copyable code.