Back to Blog
Tutorial8 min readMay 20, 2026

How to Animate SVG Icons with CSS: A Step-by-Step Tutorial

Entrance effects, looping motion, hover triggers, and the classic "draw" effect — all with a few lines of CSS and zero JavaScript. Copy-paste examples included.

I

Icora Team

Engineering

An SVG icon being animated with CSS keyframes

SVG is markup, which means every shape inside it is a DOM element you can target with CSS. That single fact makes icon animation almost embarrassingly simple: no library, no runtime, no After Effects export pipeline. A few keyframes and you are done. This tutorial walks through the patterns that cover practically every icon animation you will ever ship.

Setup: Where the CSS Lives

You have two options. If the SVG is inlined in your HTML, animate it from your normal stylesheet like any other element. The more interesting option: put a <style> block inside the SVG file itself. A self-contained animated SVG plays everywhere SVGs render — including inside a plain <img> tag, as a CSS background, even in Markdown docs.

Code
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
  <style>
    @keyframes fade-in {
      from { opacity: 0; transform: scale(0.8); }
      to   { opacity: 1; transform: scale(1); }
    }
    .icon-body {
      animation: fade-in 500ms ease-out forwards;
      transform-origin: center;
      transform-box: fill-box;
    }
  </style>
  <g class="icon-body">
    <path d="M12 2L2 22h20L12 2z" />
  </g>
</svg>

Save that as a .svg file, open it in a browser, and it animates. No JavaScript was involved at any point.

The Classic "Draw" Effect

The signature SVG animation — a path drawing itself — is a trick with two stroke properties. stroke-dasharray turns the stroke into dashes; if the dash length equals the path length, you get one dash covering the entire path. stroke-dashoffset slides that dash along the path. Animate the offset from "fully off" to zero, and the path appears to draw itself.

Code
@keyframes draw {
  from { stroke-dashoffset: 100; }
  to   { stroke-dashoffset: 0; }
}

.draw-me {
  stroke-dasharray: 100;   /* >= path length */
  animation: draw 1.2s ease-in-out forwards;
}

Pro Tip

You can get the exact path length once with element.getTotalLength() in the browser console — or just overshoot. Setting dasharray larger than the path length still works; only the timing curve gets slightly less precise.

Looping Animations: Pulse and Spin

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

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

.pulsing { animation: pulse 2s ease-in-out infinite; }
.spinning { animation: spin 1s linear infinite; }

Warning

The number one SVG animation gotcha: transform-origin. By default, SVG elements rotate and scale around the SVG canvas origin (top-left), not their own center — so your "spin" orbits off-screen instead of rotating in place. Fix it with `transform-origin: center` plus `transform-box: fill-box` on the animated element.

Hover-Triggered Playback

Because the animation is CSS, interactivity is just selectors. The cleanest pattern keeps the animation defined but paused, and lets hover resume it:

Code
.icon .wiggle {
  animation: wiggle 0.6s ease-in-out infinite;
  animation-play-state: paused;
}
.icon:hover .wiggle {
  animation-play-state: running;
}

Always: Respect Reduced Motion

Some users enable "reduce motion" at the OS level — for comfort, for vestibular disorders, or simply by preference. Honoring it in CSS is one media query, and there is no excuse to skip it:

Code
@media (prefers-reduced-motion: reduce) {
  .icon-body, .draw-me, .pulsing, .spinning {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
  }
}

When You Don't Want to Hand-Write This

Everything above is genuinely all you need for hand-rolled icon animation. If you are producing icons at volume, the Icora Studio bakes these same patterns — entrance, attention, looping, and exit presets, with stagger and easing controls — directly into exported SVGs, each with the reduced-motion query included automatically. And if you ever need the static version back, animations strip cleanly with one click. For the philosophical case for CSS-in-SVG over animation runtimes, see our piece on why SVG animations will outlive Lottie.

Generate an icon, pick an animation preset, and export a self-contained animated SVG at icora.io/create — then open it in a text editor to see exactly these patterns inside.

Try Icora Free
Tags:animate SVG with CSSSVG animation tutorialCSS icon animationanimated SVG iconsstroke-dashoffset draw effect

Found this helpful? Share it!

Ready to Create Stunning Icons?

Put these principles into practice with Icora's AI-powered icon generator, professional studio tools, and developer-ready export.

Start Creating Free