Entrances, attention-seekers and loops
The twelve presets fall into three families. Entrances (fades, slides, zoom) run once when content appears — pair them with animation-fill-mode: both, already included in the copied code where it matters, so the element holds its start and end states. Attention-seekers (bounce, pulse, shake, wobble, heartbeat) run once or twice on events like validation errors. Loops (spin, and pulse at slow speed) run forever on spinners and live indicators.
Timing that feels right
Micro-interactions live between 150ms and 400ms; entrances up to 600ms; anything above a second starts to feel like waiting. Respect users who opt out of motion: wrap the animation in @media (prefers-reduced-motion: no-preference) — shake and bounce are exactly the kind of movement that setting exists for.
Frequently asked questions
Does anything get uploaded?
No. The animation runs in your browser, so the preview is the real timing.
Which properties are cheap to animate?
transform and opacity, because the compositor handles them without recalculating layout. Animating width, height, top or left forces layout on every frame.
Why is my animation janky on mobile?
Almost always animating a layout property rather than a transform. Moving with translate rather than left is usually the whole fix.
Should I respect reduced motion?
Yes. Wrap decorative animation in a prefers-reduced-motion query — for some people motion causes genuine nausea, and it is two lines of CSS.
Something wrong with this tool, or an idea for it? Tell us