Early preview · Six skills are always free. Paid skills open soon.
Website animation · 2 min read

Respect prefers-reduced-motion in CSS and JavaScript

Provide an immediate state in CSS, listen for preference changes in JavaScript, and cancel active movement when needed.

Editorial illustration of a wind chime wrapped in a soft cloth to quiet its movement.

Respect reduced motion by providing an immediate, understandable state when the preference is active. CSS handles many effects directly. JavaScript animations also need a preference check and, for a long-lived component, a response when the preference changes during the session.

Start with the CSS path

css example

.panel { transition: transform 220ms ease-out; }
@media (prefers-reduced-motion: reduce) {
  .panel { transition: none; }
  html { scroll-behavior: auto; }
}

The final panel state must be expressed by normal layout or styles. Removing the transition should not leave a collapsed or invisible panel. The preference is documented by MDN; it is not a request to remove essential information.

Keep JavaScript in sync

js example

const preference = window.matchMedia('(prefers-reduced-motion: reduce)');
let animation;
function emphasize(element) {
  animation?.cancel();
  if (preference.matches) return;
  animation = element.animate(
    [{ transform: 'translateY(4px)' }, { transform: 'translateY(0)' }],
    { duration: 180, easing: 'ease-out' }
  );
}
function onChange() {
  if (preference.matches) animation?.cancel();
}
preference.addEventListener('change', onChange);
function cleanup() {
  animation?.cancel();
  preference.removeEventListener('change', onChange);
}

This browser-only example assumes the element’s normal final style is untransformed. Call cleanup when the owning component unmounts. Do not create the listener at module scope in code that also runs on a server.

Test a live preference change

Begin with motion allowed, trigger an effect, and enable reduced motion while it is active. Check that movement stops and the final state remains usable. Then trigger the interaction again. An initial check alone will miss a component that ignores later changes.

Keep overrides respectful

An in-app “less motion” switch can request even less movement. It should not force motion back on when the operating-system preference requests reduction. Essential state changes can remain immediate, with clear text and structure.

Document which effects are removed and what replaces them. Automated checks can find some problems, but visually inspect the interactions and include people with relevant accessibility needs when practical. A passing preference check does not establish that the entire interface is accessible.

References and further reading

The examples and templates above are original. These references support the definitions and documented behavior discussed in the guide.