1001Ferramentas
๐Ÿ”„Generators

SVG Spinner Loading

Gera spinner de loading SVG animado.

SVG

โ€”

SVG loading spinners: vector animation for indeterminate waits

An SVG spinner is a loading indicator built with the <svg> element, typically a circle whose stroke-dasharray renders only a partial arc, animated to rotate forever. Unlike a GIF, the SVG scales to any size without pixelation, accepts arbitrary colours from CSS variables, and weighs a few hundred bytes; unlike a pure CSS spinner, it can describe shapes that border-radius cannot โ€” dotted rings, equaliser bars, gradient strokes, multi-arc rosettes. The canonical structure is a 50×50 viewBox with one circle of radius 20, drawn with a gap so the rotation is visible:

<svg viewBox="0 0 50 50" width="32" height="32">
  <circle cx="25" cy="25" r="20" fill="none"
    stroke="#3b82f6" stroke-width="4"
    stroke-dasharray="50 100" stroke-linecap="round"/>
</svg>

Three ways to animate an SVG spinner

The cheapest method is external CSS: apply animation: spin 1s linear infinite to the SVG, with a keyframe rotating transform: rotate(360deg) around transform-origin: center. Animating transform stays on the GPU compositor and never stalls. The legacy method is SMIL via <animateTransform> inside the SVG โ€” still supported in Chrome/Firefox but deprecated in some contexts. The most flexible is the Web Animations API in JavaScript: el.animate([{rotate:'0deg'},{rotate:'360deg'}], {duration:1000, iterations:Infinity}), which lets you pause, reverse and chain timelines.

Variants: ring, dotted, bars, pulse

  • Classic ring โ€” full circle with a gap, rotating. Default for under-3-second waits.
  • Dotted ring โ€” multiple small circles around the perimeter, each fading in sequence. Material Design style.
  • Bars โ€” 8 to 12 vertical rectangles around centre, each with its own opacity keyframe offset. Used by iOS spinner since 2007.
  • Pulsing dots โ€” three dots scaling up and down with a 200 ms stagger. Friendly, common in chat "typing" indicators.
  • Infinite progress โ€” long arc that grows and shrinks while rotating. Material Design's circular progress indeterminate mode.

Accessibility, sizing and dark mode

Expose role="progressbar" and aria-label="Loading" so screen readers announce the wait. Always wrap the keyframe in @media (prefers-reduced-motion: reduce) and fall back to a static glyph or text โ€” vestibular disorders can be triggered by spinning indicators. Pick sizes around 16โ€“24 px next to a button, 32โ€“48 px for inline content, 64 px+ for full-page loaders. For dark mode, drive the stroke through a CSS variable (stroke: var(--spinner-colour, currentColor)) so it follows the theme automatically.

Libraries and inspiration

Sam Herbert's SVG-Loaders bundle (open source, MIT) shipped the de-facto reference set used by Bootstrap-era apps. Adobe's Lottie renders After Effects animations exported as JSON โ€” useful for richer celebratory loaders (a rocket lifting off, a checkmark drawn stroke by stroke) but heavier than a hand-coded SVG. For pure CSS-free spinners, spin.js and ldrs generate vector spinners with one function call. Whatever you pick, prefer 24+ frames per second of motion for smoothness; the human eye picks up jitter below ~20 fps.

FAQ

SVG or pure CSS spinner? If the shape is a plain ring, dot or bar, CSS is shorter and avoids an <svg> node. For non-circular paths, gradient strokes or multiple arcs, SVG wins.

What is the ideal size? 32โ€“48 px inside a button or card, 64โ€“96 px for full-page overlays. Anything below 16 px looks like a static dot.

Can I use a gradient stroke? Yes โ€” declare a <linearGradient> inside <defs> and reference it with stroke="url(#g)". Combine with stroke-linecap="round" for the Stripe-style fade.

Why does my spinner stutter? You are likely animating a non-composited property or running heavy JavaScript on the main thread. Stick to transform and opacity; the GPU keeps spinning even when the rest of the page is busy.

Related Tools