Skip to Content
Component ExamplesReduced Motion

Overview

Motion on the web can trigger vestibular disorders, seizures, migraines, and nausea for a significant number of users. Both macOS and Windows provide a system-level “reduce motion” preference, exposed to CSS via prefers-reduced-motion. Respecting this preference is not optional — it is a WCAG requirement. Beyond the media query, providing on-page pause controls ensures users without access to system settings can still stop distracting animations.

WCAG Criteria:

Key requirements:

  • Use the additive approach: only add animation when prefers-reduced-motion: no-preference — this means animation is off by default and only enabled for users who have not requested reduction
  • The subtractive approach (adding animation, then removing it in prefers-reduced-motion: reduce) is fragile — if the media query fails or is unsupported, users still get animation
  • Always provide an on-page pause/play button in addition to the media query, since not all users know how to change system settings
  • View Transitions API and CSS transition should also respect this query
  • Consider reducing motion rather than removing it entirely — a crossfade instead of a slide, for example

Animation Preference

Respecting Reduced Motion vs. Ignoring Preferences

Inaccessible
<style> @keyframes bounce { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-30px); } } </style> <!-- Always animates — no respect for user preferences --> <div style="width: 60px; height: 60px; background: #7c3aed; border-radius: 12px; animation: bounce 0.8s ease-in-out infinite;"> </div> <!-- No pause button. No prefers-reduced-motion query. -->
Live Preview

This box bounces continuously. No way to pause it. Ignores prefers-reduced-motion.

Accessible
<style> @keyframes bounce { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-30px); } } /* ADDITIVE approach: animation only added when user has NOT requested reduction */ @media (prefers-reduced-motion: no-preference) { .animated-box.is-playing { animation: bounce 0.8s ease-in-out infinite; } } </style> <div class="animated-box is-playing" id="animated-box" style="width: 60px; height: 60px; background: #7c3aed; border-radius: 12px;"> </div> <!-- On-page pause control for users without system settings --> <button aria-pressed="true" onclick=" var box = document.getElementById('animated-box'); var playing = box.classList.contains('is-playing'); if (playing) { box.classList.remove('is-playing'); this.textContent = 'Play'; this.setAttribute('aria-pressed', 'false'); } else { box.classList.add('is-playing'); this.textContent = 'Pause'; this.setAttribute('aria-pressed', 'true'); } ">Pause</button>
Live Preview

Animation respects prefers-reduced-motion. Use the button to pause/play.

What’s wrong with the bad example?

  • The animation runs unconditionally with no way to stop it
  • The prefers-reduced-motion media query is completely ignored — users who have requested reduced motion in their operating system still see the bouncing box
  • There is no pause button, so even users who have not configured system-level preferences have no way to stop the distracting motion
  • This can trigger vestibular symptoms (dizziness, nausea) in affected users

Why the additive approach is better:

  • The additive approach (prefers-reduced-motion: no-preference) starts with no animation and only adds it for users who haven’t requested reduction
  • If the media query is unsupported in an older browser, the element simply doesn’t animate — a safe default
  • The subtractive approach (adding animation normally, then removing it in prefers-reduced-motion: reduce) fails dangerously: if the query isn’t supported, animation still plays for everyone
  • The on-page pause button provides a second layer of control for users who don’t know about system settings

What the user experiences:

VersionDefault behaviorWith reduced motion enabled
Bad (no media query)Bounces continuouslyStill bounces continuously
Good (additive approach)Bounces, with Pause buttonNo animation at all

Resources