What a reduced-motion preference tells you
Motion can show where a panel came from, draw attention to a changed value or make navigation feel connected. It is not equally useful to everyone. Some people prefer less movement because large shifts, zooms or continuous effects are distracting or uncomfortable. The prefers-reduced-motion media feature lets an interface respond to a preference set through the user’s operating system or browser.
The value reduce is a request to minimize nonessential motion, not a specification for one exact visual effect. It does not tell you why someone set the preference or which individual animations they can tolerate. A practical approach is to keep content and controls available, remove decorative movement, and make necessary state changes understandable without relying on animation alone. Treat motion as an enhancement rather than the only way to reveal information.
Start with a usable, still interface
Before adding animation, check that each interaction works without it. An expanding section should still expose its contents; a dialog should still open and receive appropriate focus; a loading state should still be identifiable. Text, icons and accessible labels can communicate changes that movement would otherwise suggest. Avoid making an element initially invisible in CSS and depending on an animation to bring it into view: if the animation is skipped or fails, the content may remain hidden.
For a small hover effect, a motion-free default is straightforward. In CSS, use .card { transition: none; } and then add @media (prefers-reduced-motion: no-preference) { .card { transition: transform 180ms ease; } .card:hover { transform: translateY(-4px); } }. This example is for a browser that supports the prefers-reduced-motion media feature. The card remains usable without the lift, and the rule introduces movement only when the browser reports no reduced-motion preference. Keep any focus indicator separate from the transform so keyboard users can still locate the card.
Adapt existing transitions and scrolling
If a site already applies transitions by default, add reduced-motion rules to the affected components. For example, @media (prefers-reduced-motion: reduce) { .card { transition: none; transform: none; } }. Be specific about what you remove. A short color change that clarifies a button’s state may be more useful than a sliding panel, while a persistent pulsing effect may be particularly distracting. Review what the interface communicates after each change rather than applying one rule and assuming every interaction is covered.
Scrolling deserves the same attention as component animation. CSS can disable page-level smooth scrolling with @media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }. If JavaScript calls window.scrollTo with behavior: "smooth", that call needs its own decision; the CSS rule alone does not change the argument passed to JavaScript. Whether a jump or a gentle transition is easier to follow depends on the interaction, so retain a clear destination, such as a visible heading and appropriate focus management.
Check the preference when JavaScript controls motion
In browser-side JavaScript, window.matchMedia("(prefers-reduced-motion: reduce)") returns a MediaQueryList whose matches property reflects the current preference. A scroll control could use const motionPreference = window.matchMedia("(prefers-reduced-motion: reduce)"); followed, when the control is activated, by window.scrollTo({ top: 0, behavior: motionPreference.matches ? "auto" : "smooth" });. Use this in a browser environment, not during server-side rendering where window is unavailable. Pair it with the CSS scrolling rule above so the auto option does not inherit smooth scrolling from the page.
For longer-lived animations, respond if the preference changes while the page is open. Register a change listener on the MediaQueryList, then pause or cancel decorative animation and put the component into its correct visible state when matches becomes true. If a component is removed, remove its listener as part of cleanup. Do not merely stop an animation halfway if that leaves a menu offscreen or a progress message unreadable. The final state matters as much as the absence of motion.
Test the experience, not just the media query
Test both preference states in a browser, using an operating-system setting or browser developer tools that emulate reduced motion where available. Check hover, focus, opening and closing panels, page navigation, scrolling, loading indicators and any animations started by JavaScript. Refresh the page in each state as well as changing the preference while it is open. This catches effects that run on initial load and code that reads the preference only once.
Finally, verify that reduced motion does not remove useful feedback. A control should still show that it was activated, a dialog should still be apparent, and a completed task should still have a clear result. Respecting the preference is less about eliminating every visual change than about avoiding unnecessary movement while preserving a coherent, operable interface.



