Some readers get migraines or balance problems from page motion. The OS already knows; it exposes the preference to web pages as the prefers-reduced-motion media query. Your job is to route every voluntary animation through it.
@media (prefers-reduced-motion: no-preference) {
.reading-bar { animation: reading linear;
animation-timeline: scroll(root block); }
.card { transition: transform 0.3s ease; }
}
@media (prefers-reduced-motion: reduce) {
*, ::before, ::after {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
}What reduce should mean for you
- Decorative motion stops entirely: parallax, floating badges, entrance choreography.
- Meaningful state changes keep happening, just instantly: panels open; no slide. The information arrives without the ride.
- Scroll-driven attached animations are covered by the same gate; tying them to no-preference means non-supporting or opting-out readers get the still-state layout with no visual break.
The audit that keeps it honest
- Set the OS preference on (macOS: reduce motion toggle, then reload) and click every interactive thing on the site.
- Grep your CSS for animation and transition, and check each sits inside the no-preference gate or degrades to instant.
- Do the same for JS: View Transitions, IntersectionObserver reveals, and smooth-scroll calls all need the same respect.
- Keep the !important version as a sitemap-level safety net, not your first tool; a routed animation is better design than an emergency override.
The gacor frame: motion becomes a requested feature, not a forced output. Few aesthetics on the web age faster than animated-for-its-own-sake, and one media query makes that choice respect both aesthetics.
