SVG is a document, which is the whole trick
An SVG is markup. Every shape in it is an element with attributes, sitting in the same DOM as the rest of your page. That means the entire CSS and JavaScript animation toolkit applies to it directly: no runtime, no plugin, no export step. A designer draws a path in Inkscape, you give it a class, and CSS animates it.
This is why SVG remains the right answer for icons, logos, diagrams, line illustrations and data graphics, despite Lottie existing.
The line that draws itself
The single most useful SVG technique, and it looks like magic until you know the mechanism.
A stroked path can have a dash pattern: stroke-dasharray: 10 5 means 10 units of ink, 5 of gap, repeating. Set the dash length equal to the entire length of the path and the gap equal to it too, and you have one dash covering the whole line and one gap after it. Then stroke-dashoffset slides that pattern along the path. Offset it by the full length and the ink is pushed off the end: the line is invisible. Animate the offset back to zero and the ink slides into place, which reads as the line being drawn.
.signature path {
stroke-dasharray: 1000;
stroke-dashoffset: 1000;
animation: draw 2s ease-out forwards;
}
@keyframes draw { to { stroke-dashoffset: 0; } }The number 1000 has to be at least the path’s length. Get the real one with path.getTotalLength() in JavaScript, or, much better, put pathLength="100" on the path itself. That attribute tells SVG to pretend the path is 100 units long for all dash arithmetic, whatever its real geometry, so your CSS can use 100 everywhere and never needs measuring. Almost nobody knows about pathLength and it removes the one awkward step in the technique.
Morphing one shape into another
Two routes, with a sharp limitation on both.
Animating the d attribute. Modern browsers can interpolate a path’s d between two values, in CSS or the Web Animations API. It only works when both paths have the same number of segments, of the same types, in the same order. A four-point square morphs to a four-point diamond; a square does not morph to a circle unless you build the circle out of the same four cubic segments.
A shape library. GSAP’s MorphSVG and the open-source flubber both solve the mismatch by resampling one path to match the other’s point count. This is the honest way to morph arbitrary shapes, and the results are only as good as the correspondence the algorithm guesses.
The practical workflow: draw both shapes from the same base in Inkscape or Figma so the point counts already match, and the native route just works.
SMIL, and whether to use it
SVG has its own animation elements (<animate>, <animateTransform>, <animateMotion>) known as SMIL. Chrome announced their deprecation in 2015 and reversed it; they work today in Chrome, Firefox and Safari and are not going away in practice.
They have one genuine advantage: an SVG file animated with SMIL animates when opened on its own, in an <img> tag, or as a CSS background image, where CSS-in-the-page cannot reach it. If you need a self-contained animated SVG, SMIL is the only way inside the format.
Two reasons to prefer CSS or JavaScript in a page: SMIL does not honour prefers-reduced-motion without extra work, and its timing model is a separate thing to learn for no gain when you already have the platform’s.
<animateMotion> deserves a mention: it moves an element along an arbitrary path, which CSS only gained recently through offset-path. If you need something to follow a curve, offset-path: path("M ...") with an animated offset-distance is the modern equivalent and it is compositor-friendly.
The transform trap
The most common SVG animation bug: an element rotates around the wrong point.
CSS transform-origin on an HTML element defaults to the element’s centre. On an SVG element it is resolved against the element’s own bounding box in user units, and transform-box decides which box. The fix is one line:
.gear { transform-box: fill-box; transform-origin: center; }Without it, a gear in the middle of a 1000-unit viewBox rotates around the viewBox origin and swings across the screen. Most “my SVG animation flies off” questions are this.
Size and performance
SVG is text, so it gzips extremely well: a 30KB SVG is often 4KB on the wire. Keep it small by cleaning the exported file: Illustrator and Figma both emit enormous amounts of redundant markup. SVGO removes it, typically cutting 40 to 70 per cent, and it is free.
Be careful with filters. feGaussianBlur and friends are rasterised per frame and are among the slowest things a browser does. An animated blur on a large SVG will drop frames on hardware where the same animation with no filter runs cleanly.
The free path
- Inkscape: a full SVG editor, open source, and unusually it edits the actual SVG rather than an internal model it exports from.
- SVGO: MIT-licensed optimiser, runs as a CLI or a build step.
- Glaxnimate: draws and animates SVG and Lottie together.
- flubber: MIT, path interpolation for morphs.
- GSAP: free for all uses now, including MorphSVG and DrawSVG.
The limitation
SVG animation scales badly with element count in exactly the way Lottie’s SVG renderer does, and for the same reason: each shape is a DOM node and the browser does style and layout work on all of them. A hundred animated nodes is comfortable; a thousand is not, and the fix is to move to canvas, at which point you have given up the thing that made SVG attractive.
It is also bad at anything photographic. An SVG containing a traced photograph is thousands of paths, larger than the JPEG, and slow. The format is for drawings, and it is excellent at drawings.
Every lesson here is open. Your progress is recorded once you pass the Video with AI exam.
Check your understanding
Why does setting pathLength=”100” on an SVG path make a self-drawing line animation easier to write?
Pick the one you would defend. Your answer stays private.
Stuck on something?Ask Deepa, your AI tutor
