Designing for reduced motion
prefers-reduced-motion lets motion-sensitive users opt out of large animation. Reduce or replace the motion — keep the feedback — don't strip it all.
In one line: some people get physically sick from large on-screen motion; prefers-reduced-motion is how they tell you, and your job is to reduce or replace the motion — not delete every transition.
What it is
A meaningful share of users have vestibular disorders: big parallax scrolls, zoom transitions, and elements flying across the screen can trigger nausea, dizziness, or migraines. Operating systems expose a "reduce motion" setting, and the browser surfaces it to CSS and JS as the prefers-reduced-motion media query.
Honouring it is a WCAG requirement (2.3.3, Animation from Interactions). But "reduced" is the key word — it does not mean "no animation." A 150ms opacity fade or a focus ring transition is fine and even helpful; what hurts is large travel, scale, and parallax.
Why it matters
Motion that one person finds delightful can make another person physically ill. Respecting the setting is the difference between an interface someone can use all day and one that gives them a headache in five minutes.
It is also low-effort and high-trust: the platform already collects the preference, so you only have to listen. Getting it right signals craft; ignoring it is one of the most common, and most avoidable, accessibility failures.
See it
Tweak it2
Replay the entry at full motion, then switch on Simulate prefers-reduced-motion and compare the three techniques — reduce the move, replace it with a crossfade, or remove it entirely. The card still appears; it just stops travelling.
How it works
Author the full-motion experience as the default, then pare it back inside a reduce block. Doing it this way (rather than adding motion only under no-preference) means a browser that doesn't understand the query still gets a sensible, calm baseline.
You have three moves, roughly in order of preference:
- Reduce — keep the animation but shrink the distance/scale and shorten the duration.
- Replace — swap travel for a plain opacity crossfade, preserving the "something changed" signal without the movement.
- Remove — for purely decorative motion (auto-playing parallax, looping background), turn it off outright.
The same idea applies in JS: read matchMedia("(prefers-reduced-motion: reduce)") before kicking off a scripted animation, and respect changes to it.
Build it
.card {
transition: transform 320ms cubic-bezier(0.2, 0.7, 0.2, 1), opacity 320ms ease;
}
.card[data-enter="from"] {
transform: translateY(12px) scale(0.96);
opacity: 0;
}
@media (prefers-reduced-motion: reduce) {
.card {
/* Replace travel with a short crossfade; drop the transform entirely. */
transition: opacity 120ms ease;
}
.card[data-enter="from"] {
transform: none;
}
/* Kill decorative, self-running motion outright. */
.parallax,
.marquee {
animation: none;
}
}Make it yours
Use the controls beside the demo above to change reduced-motion technique and simulate prefers-reduced-motion — each change updates the example live.
Experiment in the playground- Compare replace and remove: replace keeps a gentle fade so the change is still legible; remove is instant, best reserved for decoration.
- Notice the card never just disappears — reduced motion is about comfort, not stripping feedback.
- Imagine a parallax hero: that is the kind of large, self-running motion the
reduceblock should switch off completely.
Reproduce it with an LLM
Reproduce it with an LLM
You are a senior front-end engineer who cares about vestibular accessibility. Take a card that animates in by sliding up 12px and scaling from 0.96 (320ms) and make it safe under `prefers-reduced-motion: reduce`: keep the meaning (the card still appears with a quick ~120ms opacity crossfade) but remove the travel and scale that can trigger motion sickness. Use a `@media (prefers-reduced-motion: reduce)` block — default to full motion, then pare it back — rather than the reverse. Also disable any parallax/auto-playing motion. Animate only transform and opacity. Return only the HTML and CSS.
Pitfalls & accessibility
Related
Motion principles
Borrowed from classic animation: timing, anticipation, follow-through, and staging turn a mechanical move into one that reads as intentional.
Scroll-driven reveals
Let content fade and rise into place as it enters the viewport — an enhancement that must never hide content when JavaScript doesn't run.