Respect prefers-reduced-motion
Check reduced motion in CSS and JS; swap big motion for a fade.
From nextjs-pagespeed.
Parallax and a count-up
Play intro, then tick Simulate reduce and replay.
Ignores the settingBad
Collected in September$48,250
–
Checks matchMediaGood
Collected in September$48,250
–
const motion = matchMedia("(prefers-reduced-motion: reduce)");
if (motion.matches) {
counter.textContent = format(TARGET);
fadeIn(layers, 200);
} else {
flyIn(layers);
countUp(counter, TARGET);
}
CSS obeys, JavaScript forgets
Tick Simulate reduce, then press Send.
Media query onlyBad
Draft
Client
–
CSS + matchMediaGood
Draft
Client
–
@media (prefers-reduced-motion: reduce) {
.toast { transform: none; }
}
if (motion.matches) place(dot, 1);
else tween(600, (p) => place(dot, p));
Read once vs subscribe
Press Start, then toggle Simulate reduce.
Read at loadBad
Syncing
const REDUCE = mq.matches;rotate: offListens for changeGood
Syncing
mq.addEventListener("change", …)rotate: offmotion.addEventListener("change", () => {
motion.matches ? stopLoop() : startLoop();
});
Why it matters, pros and cons
Why it matters
Parallax and long travel can make vestibular users sick; JS must ask matchMedia.
Pros
- One listener, near-zero cost.
- Reduced path does less main-thread work.
- Content is readable at once.
Cons
- Reduce is not remove; keep explanatory fades.
- Two paths to test, or one rots.
- User-driven motion, like a drag, can stay.