Blog / SVG/CSS

SVG Animations: Complete Guide from Line Draw to Morphing

Master the art of animating your SVGs with CSS and SMIL. From the classic line drawing effect to advanced shape morphing, discover all the techniques to bring your icons and illustrations to life.

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.

💡
Why animate with SVG?

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.

Checkmark
Cercle
Rectangle
line-draw.css
/* 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:

get-path-length.js
// 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;
💡
Pro tip

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.

Click to morph Play/Pause (click)
Click to morph Menu/Close (click)
morph-icon.css
/* 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");
}
morph-icon.js
// 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';
  }
}
⚠️
CSS morphing compatibility

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

Loader
Soleil
Steps
svg-rotate.css
.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
Bounce
Shake
svg-effects.css
/* 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
Fill fade
color-animation.css
/* 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.

Cercle pulsant
Rotation SMIL
Mouvement easing
smil-animations.svg
<!-- 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 advantage

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

Spinner
Dots loader
Bars loader

Status icons

Success
Error
Warning
success-icon.svg
<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 filter effects 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
performance.css
/* 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:

accessibility.css
/* 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 and accessibility

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.html
<!-- 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-dasharray and stroke-dashoffset for 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
🎨
Explore our library

Find over 50 animated SVG icons and illustrations ready to use in our effects library, with one-click copyable code.