Animated Icons

Pro

Motion for any glyph in the kit — 27 presets plus a curated default per icon, driven by the Web Animations API with no CSS file and no animation library. Five triggers (hover, click, in-view, mount, manual) and `prefers-reduced-motion` honoured before anything plays.

</>sv-animated-icon-pro iconanimationmotion
import { SvAnimatedIconProComponent } from '@styloviz-pro/icons';

Demo & usage

Basic usage

Pro

Usage example — open the gallery for the full interactive demo.

Pro

An interactive demo for this component lives in the gallery.

Open live demo

More examples

The curated motion, per glyph

Pro

`animation` defaults to `default`, which resolves the motion chosen for that specific glyph — a bell rings, a trash lid tips, a check draws itself on. That is the reason to reach for this component over the directive: you get the right motion without picking one for all 687 glyphs.

A named preset, looping

Pro

Name a preset to override the curated choice. `loop` repeats until something stops it, which is what a spinner wants and what a hover affordance does not.

Driven by your own state

Pro

`trigger="manual"` hands control over. Bind `play` for a declarative state, or call `start()` / `stop()` on the component when the moment comes from an event rather than a signal.

On scroll, once

Pro

`in-view` plays when the icon enters the viewport, via IntersectionObserver. `viewOnce` is on by default — an icon that re-animates every time it scrolls back into view is the thing people disable animation over. `viewMargin` starts it early.

The directive, on an icon you already have

Pro

The component is `sv-icon-pro` with the directive applied and the name forwarded. Use `svAnimate` directly to animate an icon that is already placed — including a per-icon component, which has no `name` for the resolver to read, so pass `svAnimateFor` to get that glyph's curated motion.

Timing overrides

Pro

`speed` scales the preset; `duration` and `easing` replace what it declares. Prefer `speed` — a preset's duration is tuned to its own keyframes, and a flat override is what makes a draw finish before the stroke has arrived.

When to use

  • Giving one icon a moment of motion: a bell on a new notification, a spinner during a sync, a check when something saved.
  • You want the motion that suits each glyph without choosing one per icon — `default` already resolves it.
  • For a page-wide loading state use a Spinner or Skeleton; an animated icon draws the eye to one spot, which is wasted on a whole screen.

Async states

None — this component has nothing to load, so it has no loading, empty or error state to drive.

Inputs

NameTypeDefaultDescription
namerequiredIconProName | IconName | (string & {})—Icon name (free or Pro).
sizeIconSize'md'Rendered size in px, or a named token (`sm`/`md`/`lg`).
strokeWidthnumber1.75Stroke width in viewBox units.
weightIconProWeight'line'Visual weight: `line` · `solid` · `sharp` · `duotone`.
titlestring | nullnullAccessible label. When set the icon is `role="img"`; otherwise `aria-hidden`.
flipIconFlipnullMirror the icon horizontally or vertically.
rotatenumber0Rotate clockwise, in degrees, around the centre.
cssClassstring''Extra CSS classes on the root `<svg>`.
animationIconAnimationName | string'default'Motion to play; `default` uses the glyph's curated motion.
triggerSvAnimateTrigger'hover'What starts the animation.
loopbooleanfalseRepeat until stopped.
playbooleanfalseControlled play state — used when `trigger="manual"`.
delaynumber0Start delay in ms.
speednumber1Playback rate multiplier.
durationnumber | nullnullOverride the motion's duration in ms.
easingstring | nullnullOverride the motion's easing.
persistbooleanfalseKeep the end state after finishing.
viewOncebooleantrueFor `in-view`: animate only once.
viewMarginstring'0px'For `in-view`: IntersectionObserver root margin.

Outputs

EventPayload typeDescription
animationStartstringEmits the resolved motion key when playback starts.
animationDonestringEmits the resolved motion key when a non-looping playback finishes.

Customization & theming

  • Pick the motion with `animation` — `default` for the glyph's curated choice, or one of 27 presets (`draw`, `draw-loop`, `pulse`, `spin`, `spin-ccw`, `spin-slow`, `beat`, `ring`, `swing`, `wobble`, `jello`, `tada`, `shake`, `flash`, `blink`, `pop`, `bounce`, `float`, `flip`, `sweep`, `fly`, `hinge`, `rotate-in`, `nudge-right`, `nudge-left`, `nudge-up`, `nudge-down`).
  • Choose what starts it with `trigger` (hover · click · in-view · mount · manual); with `manual`, bind `play` or call `start()` / `stop()`.
  • Shape the timing with `delay`, `speed`, `duration` and `easing`; `loop` repeats and `persist` keeps the end state instead of resetting.
  • Tune `in-view` with `viewOnce` and `viewMargin` (an IntersectionObserver root margin).
  • Everything `sv-icon-pro` takes is forwarded: `name`, `size`, `weight`, `strokeWidth`, `title`, `flip`, `rotate` and `cssClass`.
  • React to `animationStart` / `animationDone` — both emit the RESOLVED motion key, so a handler can tell which motion `default` picked.
  • Apply `svAnimate` directly to any icon you have already placed; pass `svAnimateFor` when the icon is a per-icon component with no `name` for the resolver to read.

Best practices

  • Do: Leave `animation="default"` unless you have a reason. The per-glyph choices are curated, and a generic `pulse` on everything reads as a page that is merely busy.
  • Do: Set `title` on an icon whose motion is the status — a spinning glyph that says nothing announces nothing, and the motion is exactly the information a screen-reader user cannot see.
  • Do: Reserve `loop` for state that is genuinely ongoing (syncing, recording). A looping decoration never stops competing with the content beside it.
  • Tip: Scale timing with `speed` rather than replacing `duration`; each preset's duration is tuned to its own keyframes.
  • Don't: Don't use motion as the only signal that something changed. `prefers-reduced-motion` suppresses playback entirely, so anyone on that setting sees a static icon and no state at all.
  • Don't: Don't animate more than one or two icons in a view. The point of motion is that it is the only thing moving.

Accessibility

  • `prefers-reduced-motion: reduce` suppresses playback entirely — the icon renders in its resting state rather than playing a shortened version, because a smaller amount of the thing that triggers vestibular symptoms is still that thing.
  • Motion never carries meaning on its own. Set `title` when the animation IS the status: it names the glyph `role="img"`, which is the only part of a spinning icon that reaches a screen reader.
  • Playback is Web Animations API only, with no CSS keyframes and no library, so it degrades to a static icon under SSR and on any runtime without WAAPI instead of throwing.
  • The animation runs on transforms and stroke properties, so it never moves the glyph out of its box and never reflows the text beside it.
  • `animationDone` fires with the resolved motion key on non-looping playback, so a host can wait for the motion to finish before moving focus rather than guessing at a duration.

Feedback on Animated Icons

Spotted a gap in this page, or something that didn't work as described? Comments are GitHub Discussions in the public styloviz/community repo, so posting needs a GitHub account.

Loads giscus.app and GitHub — nothing is fetched until you click.