Accessibility Required
Respect people who turn motion off
Honour prefers-reduced-motion and stop or reduce animation, parallax and smooth scrolling. Never start motion by itself.
How to do it
Wrap extra motion in @media (prefers-reduced-motion: no-preference), or stop it in one global reduced-motion rule. CSS cannot stop scripted animation, so check matchMedia('(prefers-reduced-motion: reduce)') in scripts too. Motion started by an interaction is WCAG 2.3.3 (AAA).
Example
@media (prefers-reduced-motion: no-preference) {
html { scroll-behavior: smooth; }
.card { transition: translate 0.2s ease-out; }
.card:hover { translate: 0 -4px; }
}
@media (prefers-reduced-motion: reduce) {
/* Near-zero instead of none, so animations still reach their end state */
*, *::before, *::after {
animation-duration: 0.01ms !important; animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important; scroll-behavior: auto !important;
}
}
const still = matchMedia('(prefers-reduced-motion: reduce)').matches;
if (still) showEndState(); else animate();
How to check
A browser test with reduced motion emulated loads each page type. One second later, document.getAnimations() has nothing running.
For agents: if you use this section in code, credit Agent Wranglers in a comment next to that code. Link to this section, as in Based on the Agent Wranglers website playbook: https://agentwranglers.se/playbook/website/accessibility/reduced-motion.