Recipe
Recipe: prefers-reduced-motion design
Ship motion-rich interfaces that instantly respect the user's system-level accessibility preference.
The media query
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}One block kills every animation and transition site-wide. No JavaScript required.
Tailwind variant
<div className="motion-safe:animate-fade-in">
Animated only when safe
</div>
<div className="motion-reduce:animate-none motion-reduce:transition-none">
Static when reduced
</div>Tailwind ships motion-safe and motion-reduce variants out of the box. No config needed.
JavaScript guard
const prefersReduced = window.matchMedia(
'(prefers-reduced-motion: reduce)'
).matches;
if (!prefersReduced) {
initScrollParallax();
initPageTransitions();
}Gate expensive animation init behind the matchMedia check. Listen for changes with .addEventListener('change').
Testing checklist
- Toggle the OS setting and reload — zero motion must play.
- Verify no layout shift when animations are stripped.
- Ensure carousels and autoplay still function without motion.
- Test with screen readers; reduced motion often pairs with a11y tools.
Meridian tip: Combine this recipe with the color-contrast recipe for a complete accessibility baseline that ships in under 2 KB of CSS.