CSSAccessible Animations

Accessible Animations

Animation can genuinely improve an interface — drawing attention to a change, showing spatial relationships, easing a transition between states. It can also actively harm some users if it isn't built with a few accessibility considerations in mind. This page builds on prefers-reduced-motion and covers what else responsible motion design needs to account for.

Recap: prefers-reduced-motion

The starting point for any non-trivial animation is respecting the prefers-reduced-motion media query, which reflects a system-level setting some users enable because motion causes them dizziness, nausea, or triggers vestibular disorders. See prefers-reduced-motion for the full details — the short version:

CSS
@media (prefers-reduced-motion: reduce) {
  * {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}
Flashing content and seizure risk

Beyond motion sensitivity, rapidly flashing content is a genuine WCAG requirement, not a stylistic preference — certain flash patterns can trigger seizures in users with photosensitive epilepsy. WCAG's general guidance is to avoid content that flashes more than three times per second, and to avoid large-area flashes combining red with other saturated colors, unless the flash is below the guideline's size and contrast thresholds.

Warning
Avoid rapid strobing effects entirely — fast-blinking banners, loading indicators that flash sharply, or attention-grabbing animations that alternate between two high-contrast states many times per second. If an effect needs to draw attention, a slower pulse, a color transition, or a subtle scale change communicates the same thing without the seizure risk.
Animations that interfere with reading or focus

A few less obvious considerations round out accessible motion design:

  • Avoid animating text a user is expected to read while it's moving — scrolling marquees or bouncing headlines make reading measurably harder for users with cognitive or attention-related disabilities, and are mildly annoying for everyone else.

  • Don't let an animation trap keyboard focus — if a modal or carousel animates in, focus should move to it (or stay put) predictably, not get lost mid-transition or land somewhere unexpected.

  • Time screen-reader announcements around animation, not against it — if content animates in and an ARIA live region announces it immediately, make sure the announcement isn't cut off or delayed in a confusing way by the transition itself.

  • Provide pause/stop controls for any animation that repeats indefinitely and lasts more than a few seconds — auto-playing carousels and looping background video are common offenders.

Worked example: decorative animation with a fallback

CSS
/* A subtle looping "shimmer" on a loading skeleton — purely decorative,
   conveys no information beyond "content is loading" */
.skeleton {
  background: linear-gradient(
    90deg,
    #eee 25%,
    #f5f5f5 37%,
    #eee 63%
  );
  background-size: 400% 100%;
  animation: shimmer 1.4s ease-in-out infinite;
}

@keyframes shimmer {
  0% { background-position: 100% 50%; }
  100% { background-position: 0% 50%; }
}

/* Reduced-motion fallback: keep the loading indication (the gray
   block itself is still visible and communicates "loading") but drop
   the moving animation entirely rather than slowing it down */
@media (prefers-reduced-motion: reduce) {
  .skeleton {
    animation: none;
    background: #eee;
  }
}
Note
A good rule of thumb: if removing an animation would remove information (like a progress indicator actually communicating progress), keep a non-animated equivalent rather than nothing at all. If an animation is purely decorative, it's always safe to disable it completely under reduced motion.
Next
Review the base pattern on [prefers-reduced-motion](/css/reduced-motion), and see how motion and color choices intersect with [High Contrast & forced-colors](/css/high-contrast).