← Back to Blog Tutorial

How to Animate SVG in CSS

From simple fade-ins to stroke draw effects — learn how to bring SVG illustrations to life with pure CSS animations, no JavaScript required.

June 2025 · 7 min read

CSS animations work beautifully with SVG. Because SVG elements are just DOM elements, you can apply the same @keyframes animations you'd use on any HTML element — but with far more control over individual shapes, paths and colors within the illustration.

Animations covered: Fade In Float Bounce Pulse Spin Stroke Draw

The basics: how CSS animation works on SVG

To animate an SVG, you either:

  • Add a CSS class to the <svg> element and animate the whole illustration, or
  • Target individual child elements (path, circle, rect, etc.) for more granular effects

One important quirk: for transform-based animations (rotate, scale, translate) to work correctly in SVG, you need to set these two CSS properties:

.my-svg {
  transform-origin: 50% 50%;
  transform-box: fill-box;
}

transform-box: fill-box makes the transform origin relative to the element's own bounding box rather than the viewport — without this, rotations and scales often behave unexpectedly.

1. Fade In

The simplest animation. Great for hero illustrations that appear as the page loads.

@keyframes fadeIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}

.illustration {
  animation: fadeIn 0.8s ease-in-out forwards;
}

2. Float

A gentle up-and-down motion. Perfect for hero illustrations, empty-state graphics, or product mockups.

@keyframes float {
  0%, 100% { transform: translateY(0); }
  50%       { transform: translateY(-14px); }
}

.illustration {
  animation: float 3s ease-in-out infinite;
}

3. Bounce

Drops in from above and bounces to a rest position. Good for success states or confirmation screens.

@keyframes bounce {
  0%   { transform: translateY(30px); opacity: 0; }
  60%  { transform: translateY(-8px); opacity: 1; }
  80%  { transform: translateY(4px); }
  100% { transform: translateY(0);   opacity: 1; }
}

.illustration {
  animation: bounce 0.7s cubic-bezier(0.36, 0.07, 0.19, 0.97) forwards;
}

4. Pulse

Gently scales the illustration up and down. Works well for attention-grabbing CTAs or notification indicators.

@keyframes pulse {
  0%, 100% { transform: scale(1); }
  50%       { transform: scale(1.08); }
}

.illustration {
  transform-origin: 50% 50%;
  transform-box: fill-box;
  animation: pulse 2s ease-in-out infinite;
}

5. Spin

Continuous rotation around the Z axis. Use sparingly — good for loading indicators or icon badges.

@keyframes spin {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}

.illustration {
  transform-origin: 50% 50%;
  transform-box: fill-box;
  animation: spin 2s linear infinite;
}

6. Stroke Draw Effect

This is the most impressive CSS SVG technique — it makes paths appear to draw themselves. It relies on the stroke-dasharray and stroke-dashoffset properties.

How it works

SVG strokes can be rendered as dashes. stroke-dasharray sets the length of each dash; stroke-dashoffset shifts where the dash pattern starts. By setting both to the total path length, the stroke is invisible. Animating stroke-dashoffset to 0 makes it appear to draw in from the start of the path.

/* Step 1: Measure the path length in JS */
const path = document.querySelector('.my-path');
const length = path.getTotalLength();

/* Step 2: Set initial state */
path.style.strokeDasharray  = length;
path.style.strokeDashoffset = length;

/* Step 3: Trigger the animation */
path.style.animation = 'draw 2s ease-in-out forwards';
@keyframes draw {
  to { stroke-dashoffset: 0; }
}

Staggering multiple paths

For an illustration with many paths, stagger the animation delay so each path draws in sequence:

const paths = document.querySelectorAll('path');
const totalDuration = 2; // seconds

paths.forEach((path, i) => {
  const length = path.getTotalLength();
  const delay  = (i / paths.length) * totalDuration * 0.75;

  path.style.strokeDasharray  = length;
  path.style.strokeDashoffset = length;
  path.style.animation = `draw 1s ease-in-out ${delay}s forwards`;
});
No-code option: The SketchValley SVG Animation tool applies all of the above animations to any SVG you upload — including the stroke draw effect. Choose the animation, set speed and loop, then download the animated SVG.

Applying animations only to specific elements within an SVG

You can target individual elements inside an SVG by giving them an id or class:

<svg>
  <circle id="planet" cx="200" cy="200" r="80" fill="#586EFF"/>
  <path class="orbit-ring" d="M 50 200 A 150 150 0 1 1 350 200"/>
</svg>
#planet {
  transform-origin: 50% 50%;
  transform-box: fill-box;
  animation: pulse 3s ease-in-out infinite;
}

.orbit-ring {
  animation: draw 2s ease-in-out forwards;
}

Respecting user preferences

Always wrap motion animations in a prefers-reduced-motion media query. Some users experience motion sickness from animations, and it's a simple accessibility fix:

@media (prefers-reduced-motion: reduce) {
  .illustration {
    animation: none;
  }
}

Animate any SVG illustration

Upload an SVG, choose an animation style, preview it live, and download the animated file — all in your browser.

Try the SVG Animation tool →