What is prefers-reduced-motion — and why less motion doesn't mean no animation

In 2013 Apple shipped iOS 7. Parallax wallpapers, apps that zoom out of their icons. Pretty. And along with it, the settings got a Reduce Motion switch — so all of that could be turned off.
Today every operating system has this setting. And a website reads it with one line of CSS: prefers-reduced-motion.
Here's the catch. A developer's first reaction is "I'll turn off every animation and be done." WebKit engineer James Craig warned back in 2017 that this only makes a site boring. You don't remove all motion — you remove specific kinds that make people physically unwell.
What it is
prefers-reduced-motion is a media query. It has two values:
no-preference— the person didn't ask for anything;reduce— Reduce Motion is on in the system.
Where people turn it on:
- iPhone: Settings → Accessibility → Motion;
- Android 9+: Accessibility → Remove animations;
- Windows 11: Accessibility → Visual effects → Animation effects;
- macOS: Accessibility → Reduce motion.
The browser passes that choice to the page. Chrome, Firefox and Safari have supported the query for years.
Why people need it
The main reason is vestibular disorders: problems with the inner ear and the parts of the brain that handle balance. The eyes see everything sliding, while the body stands still. The brain gets conflicting signals — and the person feels motion sick, like in a car.
It isn't rare. In a 2009 Johns Hopkins study, a balance test found vestibular dysfunction in 35.4% of US adults over 40. The WCAG guidance describes reactions to unnecessary motion: nausea, migraines, sometimes needing to lie down to recover.
And some people turn the setting on simply because motion is distracting. That's a legitimate reason too.
Which motion makes people sick, and which is fine
The same WebKit article lists the typical triggers:
- zooming and scaling — the feeling of flying forward or backward;
- spinning and spirals;
- movement at different speeds or in different directions — classic parallax;
- plane shifting — flat cards that rotate in 3D;
- peripheral motion — the background moves while you read.
What's usually safe:
- fading in through opacity;
- color changes;
- things the person controls directly: scrolling with a finger, pinch to zoom.
Hence the rule: with reduce, don't delete the animation — replace it. The card doesn't fly in from below; it calmly appears in place.
How to handle it on your site
In CSS, it's one media query:
.card {
animation: slide-up 0.5s ease both;
}
@media (prefers-reduced-motion: reduce) {
.card {
animation-name: fade-in;
}
html {
scroll-behavior: auto;
}
}
The second part turns off smooth scrolling to anchors. That's also motion the person's finger didn't start.
In JavaScript — for carousels, autoplay video and canvas effects:
const reduce = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
if (!reduce) {
startParallax();
}
A person can flip the setting without closing the tab. To stop an effect right away, listen for the change — the WebKit article does exactly that:
const query = window.matchMedia('(prefers-reduced-motion: reduce)');
query.addEventListener('change', () => {
if (query.matches) stopParallax();
});
And separately, about things that start on their own, with no action from the person: auto-playing carousels, background videos, scrolling tickers. WCAG has a different criterion for them — 2.2.2 "Pause, Stop, Hide", level A, the basic one. If that kind of motion lasts more than five seconds and runs alongside other content, people must be able to stop it — even if they never turned on any setting.
Tailwind has motion-safe: and motion-reduce: variants — the first adds an animation only for people who didn't ask to remove it. That way you don't have to "undo" every movement later. How such classes differ from hand-written CSS is covered in Tailwind vs CSS.
Now an important one if you build interfaces with AI. The popular Motion library (formerly Framer Motion) ignores the setting by default: reducedMotion on MotionConfig defaults to never. One wrapper fixes it:
import { MotionConfig } from 'motion/react';
export function App({ children }) {
return <MotionConfig reducedMotion="user">{children}</MotionConfig>;
}
With "user", the library disables transform and layout animations but keeps opacity and background color. Exactly the replacement described above.
You can test without changing system settings in Chrome: DevTools → More tools → Rendering → "Emulate CSS media feature prefers-reduced-motion" → reduce. It's especially worth walking through your landing page: that's usually where the first screen has the most animation.
There's a similar setting for color, too — forced colors mode, where Windows repaints the site with the person's palette.
Short story-lessons, an agent simulator and daily practice — in our mobile app. Free.
What if the interface gets confusing without animation?
Then don't remove it — simplify it. WebKit's advice: if the motion carries meaning, like showing where an item flew to, replace it with a simpler version or another visual cue.
Is this a mandatory requirement?
WCAG 2.3.3 "Animation from Interactions" is level AAA, the strictest. It's usually not treated as mandatory. But it costs one media query and can save someone a wave of nausea.
Can I add a toggle right on the site?
Yes, and WCAG gives it as an example: one site-wide control turns off non-essential animations. Motion supports this with reducedMotion="always" and "never" — you can set them from a preference in the person's profile.
Do I need to remove every transition?
No. A button changing color on hover or a tooltip fading in doesn't make anyone sick. Go after big motion: zooms, parallax, things flying across the whole screen.





