ICON OOP
Icons & Logos
Browse

Animated SVG icons

An animated icon is a self-contained SVG file with CSS or SMIL inside it. Drop it in and it moves. The interesting question is not how to animate an icon, it is when you should, and every good answer to that is about restraint.

HomeBrowseAnimated icons

ICON OOP includes a small set of original animated SVG icons, drawn and animated for this site. Each is a single self-contained .svg file with the animation defined inside it. No JavaScript library, no build step, no runtime dependency.

They cover the cases where motion genuinely does work: a loading spinner, a ticking clock, a ringing bell, a drawing checkmark, a pulsing status dot.

The principle

Animate an icon when the motion communicates something: that work is happening, that something arrived, that a state changed. Do not animate an icon because the animation looks nice. A page where several icons move at once has no way to signal that something actually needs attention.

The three ways to animate an SVG

MethodHow it worksVerdict
CSS inside the SVGA <style> block with keyframes, inside the fileThe right default. Works standalone or inline
SMIL<animate> and <animateTransform> elementsGood for path morphing, deprecated-then-unreally, but well supported
JavaScriptGSAP, anime.js, Web Animations APIOnly when you need interaction or sequencing

The icons on this site use CSS inside the file, which is why they animate identically whether you inline them, load them with <img>, or set them as a CSS background. That portability is the whole reason to choose CSS over JavaScript for simple icon motion.

The one thing CSS cannot do well is morph one shape into another, since interpolating between paths with different node counts is unreliable. That is SMIL's remaining strong case, along with animating along a motion path.

Where animation earns its place

  • Loading and progress. The clearest case. A spinner tells the user the system is working and has not frozen. Anything over about a second of waiting needs one.
  • Success confirmation. A checkmark that draws itself over roughly 400ms reads as an event, which is exactly what a confirmation is. A static tick that appears is easy to miss.
  • Attention on arrival. A bell that rings once when a notification lands. Once. Not on a loop.
  • Live status. A slowly pulsing dot for a live stream or an active connection.
  • State transitions. Hamburger to close, play to pause, chevron rotating on expand. Motion here explains the relationship between the two states.

Where it does not

  • Decorative motion in feature grids. Six icons pulsing on scroll is a distraction competing with your copy.
  • Anything on an infinite loop that is not communicating ongoing activity. Loops draw the eye permanently, and the eye eventually resents it.
  • Navigation icons. Users need to find these fast; motion slows recognition.
  • Multiple simultaneous animations. Motion signals priority. Everything moving means nothing is prioritised.
  • Long entrance animations. If the icon takes 800ms to appear, the user has read past it.

A useful test: turn the animation off and ask whether anything is lost. If the answer is only "it looks less lively", leave it off.

Respecting reduced motion

This is not optional. Vestibular disorders are common, and for affected users unnecessary motion causes real nausea and dizziness. Operating systems expose a reduced motion preference and CSS lets you read it.

@media (prefers-reduced-motion: reduce) {
  .icon-animated * {
    animation: none !important;
    transition: none !important;
  }
}

Two refinements worth making. First, put the media query inside the SVG file as well as in your stylesheet, so the icon behaves correctly even when loaded standalone through an <img> tag, where your page CSS cannot reach it. Second, do not simply kill everything: a spinner that stops spinning tells the user the app has frozen. For genuinely functional motion, reduce it rather than remove it, for example fade a spinner's opacity instead of rotating it.

Performance: which properties are cheap

Not all animated properties cost the same. Some can be handled by the GPU on their own layer, others force the browser to recalculate layout or repaint on every frame.

PropertyCost
transform, opacityCheap. Composited, no layout or paint
stroke-dashoffsetModerate. Repaints, but fine for one or two icons
fill, stroke colourModerate. Repaint each frame
r, cx, width, dExpensive. Recalculates geometry every frame

Prefer transform and opacity wherever the effect allows. The classic line-drawing effect uses stroke-dasharray and stroke-dashoffset, which is more expensive but perfectly acceptable for a single confirmation checkmark. It is not acceptable for forty icons animating on scroll.

Embedding matters more than you expect

MethodAnimation runs?Page CSS can control it?
Inline <svg>YesYes, fully
<img src="icon.svg">Yes, if CSS or SMIL is inside the fileNo
CSS background-imageYes, same conditionNo
<object>YesNo, but the SVG can run its own JS

The key point: an SVG loaded through <img> is a separate document. Your page CSS cannot reach inside it, and neither can your reduced-motion rule. Self-contained files, with their own styles and their own media query, are the only ones that behave correctly in every embedding method.

Animating an icon yourself

The line-drawing effect is the most useful one to know, and it is about six lines.

<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
     stroke-linecap="round" stroke-linejoin="round">
  <style>
    .draw { stroke-dasharray: 30; stroke-dashoffset: 30;
            animation: draw .4s ease forwards; }
    @keyframes draw { to { stroke-dashoffset: 0; } }
    @media (prefers-reduced-motion: reduce) {
      .draw { animation: none; stroke-dashoffset: 0; }
    }
  </style>
  <path class="draw" d="M5 13l4 4L19 7"/>
</svg>

The idea: stroke-dasharray makes the line one long dash, stroke-dashoffset pushes that dash out of view, and animating the offset back to zero draws the line in. Set the dasharray to at least the path's total length. The full walkthrough, including getting path lengths and morphing, is in how to animate SVG icons.

Frequently asked questions

The animation is defined inside the SVG file itself, usually as a CSS style block with keyframes, sometimes using SMIL animate elements. Because everything lives in the file, the icon animates whether you inline it, load it through an img tag, or use it as a CSS background image, with no JavaScript library or build step needed.
It depends entirely on which properties you animate. Transform and opacity are composited by the GPU and are very cheap. Stroke dash offset and colour changes force a repaint each frame, which is fine for one or two icons. Animating geometry attributes such as r, cx or the path d value is expensive because the browser recalculates the shape every frame.
Wrap the animation in a prefers-reduced-motion media query and disable or reduce it when the user has asked for less motion. Put that query inside the SVG file as well as in your stylesheet, so it still applies when the icon is loaded through an img tag where your page CSS cannot reach it. For functional motion such as a spinner, reduce it rather than removing it entirely.
Only if the SVG is inlined directly in your HTML. An SVG loaded through an img tag, a CSS background or an object element is a separate document, so your page styles cannot reach inside it. That is why self-contained animated files, carrying their own styles, are more portable than ones that depend on external CSS.
Avoid animation on navigation icons, where motion slows recognition, on decorative icons in feature grids, where it competes with your copy, and on anything looping infinitely that is not communicating ongoing activity. If turning the animation off loses nothing except liveliness, it should be off.
The line-drawing effect. Set stroke-dasharray to at least the path's length so the stroke becomes one long dash, set stroke-dashoffset to the same value to push it out of view, then animate the offset to zero so the line appears to draw itself. It is roughly six lines of CSS and works well for confirmation checkmarks.

Browse animated SVG icons

Preview and download original animated SVG icons. Self-contained files, no JavaScript library required.

Open the ICON OOP tool