Animations

Keyframe animations run on their own — when a page loads, in a loop, or tied to scrolling — and can pass through many intermediate steps. They power loading spinners, attention cues, entrance effects and decorative motion.

Keyframes and the animation property

Try it yourself
Result

@keyframes defines the stages of an animation by percentage (from and to mean 0% and 100%). The animation property attaches it to an element with a name and duration, plus optional settings.

Animation properties

PropertyExampleMeaning
animation-namepulseWhich keyframes
animation-duration1sOne cycle's length
animation-timing-functionease-in-outSpeed curve (per keyframe step)
animation-delay0.5sWait before starting (negative starts part-way through)
animation-iteration-count3, infiniteHow many times
animation-directionalternatePlay forwards, backwards, or alternate
animation-fill-modeforwards, bothKeep the first/last frame's styles before and after
animation-play-statepausedPause or resume

A loading spinner

Try it yourself
Result

If a keyframe block only has to, the animation starts from the element's current style.

Entrance animations

Try it yourself
Result

animation-fill-mode: both (in the shorthand) keeps each item invisible during its delay, then holds the final state. Staggered delays create a cascade.

Alternating and multi-step

Try it yourself
Result

An element can run several animations at once, separated by commas. alternate plays forwards then backwards, avoiding a jump at the end of each loop.

Scroll-driven animations

Try it yourself
Result

animation-timeline: scroll() links an animation's progress to a scroll position instead of time; view() links it to an element's visibility as it scrolls through the viewport — great for reveal effects. Supported in Chromium-based browsers and Safari, and arriving in Firefox; elsewhere the bar simply stays as its final frame.

Animation vs transition

TransitionsAnimations
Triggered by a state changeRun on their own (load, loop, scroll)
Two states: from → toAny number of keyframes
Best for hover, focus, togglesBest for loaders, attention cues, entrances

Animate responsibly

  • Respect prefers-reduced-motion: turn off or tone down non-essential motion.
  • Avoid flashing more than three times per second — it can trigger seizures.
  • Provide a way to pause long or looping animations.
  • Prefer animating transform and opacity for smoothness.
CSS reduce.css
@media (prefers-reduced-motion: reduce) {
  .balloon,
  .heart {
    animation: none;
  }
}

Try it yourself

Try it yourself
Result