How to Animate SVG Icons Step by Step
SVG icons are the perfect candidate for CSS animation — they are resolution-independent, tiny in file size, and every shape inside them is individually targetable with CSS selectors. This guide walks through the four most useful icon animation patterns, with copy-paste code for each.
Why Animate SVG Icons Specifically?
Unlike raster icons (PNG, WebP), SVG icons expose their internal structure to CSS and JavaScript. A three-bar hamburger menu, for example, is just three <line> or <rect> elements — each of which you can rotate, translate, or fade independently.
This makes it trivial to animate common UI state transitions — hamburger to X, plus to minus, play to pause, loading spinner — entirely in CSS with no JavaScript and no external library.
Pattern 1: Rotating Spinner
The simplest animated SVG icon is a loading spinner. A circle with a partial stroke gap rotated continuously creates the classic indeterminate spinner used across every design system.
The stroke-dasharray creates the gap — 16px of visible stroke, 47px gap (roughly the remaining circumference of a circle with r=10).
Pattern 2: Draw-On Stroke Effect
The draw-on effect makes an SVG path appear to be drawn in real time. It works by setting stroke-dasharray to the total path length and animating stroke-dashoffset from that value down to zero.
How to get path length
In DevTools: document.querySelector("path").getTotalLength() — paste the result into your CSS.
Pattern 3: Hover State Transition
CSS transitions on SVG properties work exactly like on HTML elements. You can animate fill, stroke, opacity, and transforms on hover with a single transition declaration.
/* CSS */
.icon-path {
fill: none;
stroke: #A0A0A0;
stroke-width: 2;
stroke-linecap: round;
transition: stroke 200ms ease, transform 200ms ease;
transform-origin: 50% 50%;
}
.icon-btn:hover .icon-path {
stroke: #6366f1;
transform: scale(1.1);
}Pattern 4: Hamburger → X Toggle
The hamburger-to-close animation is the most common SVG icon state transition in UI. The trick is rotating the outer bars and fading the middle one.
/* CSS */
.bar {
transition: transform 300ms ease, opacity 200ms ease;
transform-origin: 12px 12px; /* center of 24x24 viewBox */
}
/* open state — add .is-open to the <svg> via JS */
.hamburger.is-open .bar.top { transform: rotate(45deg) translateY(6px); }
.hamburger.is-open .bar.middle { opacity: 0; transform: scaleX(0); }
.hamburger.is-open .bar.bottom { transform: rotate(-45deg) translateY(-6px); }Toggle the .is-open class with one line of JavaScript: el.classList.toggle('is-open')
Using CSSVG to Animate Icons Visually
Writing keyframe offsets and transform values by hand gets tedious quickly. CSSVG gives you a visual timeline so you can set keyframes by scrubbing and let the tool output the exact CSS — including easing curves.
- 1Import your SVG icon via File → Import SVG. Each sub-path or shape becomes its own animatable layer.
- 2Select a layer, drag the playhead to a time, and adjust transform / opacity / fill in the Inspector panel. A keyframe is recorded.
- 3Repeat for as many keyframes as needed. The canvas previews the animation live.
- 4Export → CSS to get a self-contained SVG + CSS file. Export → SMIL for a fully standalone animated SVG that works in img tags and emails.
Common Gotchas
transform-origin on SVG elements
In SVG, transform-origin is relative to the SVG coordinate system by default, not the element's bounding box. Always set transform-box: fill-box alongside transform-origin to get intuitive center-based rotation.
Inline SVG vs <img> tag
CSS animations only work on inline SVG — SVG loaded via <img src> is sandboxed. Use inline SVG or the SMIL export (which bakes animations into the file itself).
stroke-dashoffset direction
Positive dashoffset shifts the stroke forward (revealing it from the start). Negative shifts it backward. For a left-to-right draw, animate from pathLength → 0.
Animate Your SVG Icons Visually
Skip the hand-coding. Import your icon, set keyframes visually, and export clean CSS in seconds — free, no sign-up.
Open the Editor — it's free