Respecting reduced motion in a feedback widget

Visitors who turn on reduced motion in their operating system ask pages to stop large movement. Wrap your own trigger and page animations in a prefers-reduced-motion media query, keep fades that help orientation, and test with the OS setting turned on, then with DevTools.

By 路 Published 路 Last updated

What does prefers-reduced-motion actually ask for?

The prefers-reduced-motion media feature tells a page that the visitor has asked the operating system to reduce motion. The setting exists because large movement, such as sliding panels, zooming content and parallax, can cause dizziness, nausea or headaches for some people. The request is not a ban on all change. It asks you to replace large or repeated movement with calmer alternatives, such as a plain fade or an instant change.

Treat the setting as a user preference, not an error. Visitors who turn it on should get the same content and the same controls, with less movement.

Which animations should a feedback panel keep?

A feedback panel has a few animations that people might see: the floating button lifting when hovered, the panel sliding in from a corner, a button changing color and a success message appearing. Each one has a different job, so keep the ones that help orientation and remove the ones that only move things.

Animation Under reduced motion Why
Panel slides in from a corner Replace with an instant change or a short fade Large travel is the main trigger for discomfort
Floating button lifts on hover Remove the lift, keep the color change Color still shows the hover state
Success message fades in Keep, or show it instantly A fade is gentle and confirms the send
Spinner while sending Keep a static text status, such as "Sending" A spinner moves continuously
Looping pulse on the button Remove Repeated motion draws attention without a purpose

How do you write the CSS media query?

Write the normal motion first, then override it inside the reduced-motion query. This keeps the default easy to read and makes the exception obvious:

.feedback-trigger {
  transition: transform 200ms ease, background-color 200ms ease;
}

.feedback-trigger:hover {
  transform: translateY(-2px);
}

@media (prefers-reduced-motion: reduce) {
  .feedback-trigger,
  .feedback-trigger:hover {
    transition: background-color 200ms ease;
    transform: none;
  }
}

The color transition stays, because a color change does not move anything on the screen. Removing the lift keeps the button still while the hover state remains visible.

How do you read the setting in JavaScript?

Use matchMedia when a script needs to choose between two behaviors, such as opening your own panel with a fade or with no transition at all. Listen for changes too, because a visitor can turn the setting on while the page is open:

const motionQuery = window.matchMedia("(prefers-reduced-motion: reduce)");

function transitionFor(preferred) {
  return motionQuery.matches ? "none" : preferred;
}

motionQuery.addEventListener("change", function () {
  document.documentElement.dataset.motion = motionQuery.matches ? "reduced" : "full";
});

Prefer the CSS query where you can, because it needs no script and applies to every element at once. Use the JavaScript check only for animation logic that CSS cannot express, such as a timed sequence.

Which motion carries information and should stay?

Some motion tells the visitor something. A progress indicator that fills as a file uploads, or a caret that blinks in a text box, shows that work is happening. Replacing these with nothing can leave the visitor unsure whether a send worked. Under reduced motion, swap the moving indicator for a static one with words, such as "Sending" beside a fixed icon, and keep the text that reports the result.

Focus indicators are not motion and must not be removed. Some teams turn off every transition to be safe, and that can also remove the change that shows focus moving to a new control. Keep the focus ring visible under reduced motion, and only remove the movement around it.

Does the Escuta Produto widget respond to the setting?

Test this on your own page, rather than relying on a description. The accessible widget article describes the reduced-motion behavior the widget aims for, but motion inside the widget's Shadow DOM is outside your stylesheet. Your page CSS cannot target elements inside it, so you cannot override a widget animation with a normal selector.

What you can control is everything around the widget: your own trigger, the page content that moves when the panel opens, and any banner or toast that appears after a send. If you find motion inside the widget that does not stop with the setting on, record the screen, note the browser and operating system, and send it to the Escuta Produto team as a bug.

How do you test with the operating system setting?

Test with the real setting, not only with a simulation. Turn it on, reload the page and check every motion you control.

  1. On macOS, open System Settings, go to Accessibility, then Display, and turn on the option for reducing motion.
  2. On Windows, open Settings, go to Accessibility, then Visual effects, and turn off animation effects.
  3. On iOS and Android, use the accessibility settings for motion or animations, and check the same screens on a phone.
  4. Load the page, hover the feedback button, open the panel, send a short message and check the success state.
  5. Turn the setting off, repeat the steps and confirm the normal motion returns.

How do you test in DevTools without changing the system?

Chrome and Edge DevTools can emulate the setting for one tab. Open the Rendering panel, find the option to emulate a CSS media feature, and set prefers-reduced-motion to reduce. Reload the page and repeat the checks. This method is faster for a set of pages, but it does not replace the OS test, because the system setting can behave slightly differently in some browsers.

Checking reduced motion on a live Escuta Produto install

Add the widget as you normally would, then run the steps above on your most animated page. The attributes and options are listed in the widget docs. For the wider set of accessibility checks that apply to the same panel, read how to make a feedback widget accessible. If the trigger's wording needs to change for the same users, what a feedback button should say covers the label.

Frequently asked questions

What is prefers-reduced-motion?

A media feature that reports when a visitor has asked their operating system to reduce motion. Pages can read it in CSS or JavaScript and replace large movement with fades or instant changes, while keeping the same content and controls.

Should a feedback button stop all animation under reduced motion?

Not all of it. Remove movement such as lifts, slides and looping pulses, but keep color changes and short fades that help people see what happened. The button should still show hover and focus states clearly.

How do I test reduced motion on my feedback widget?

Turn on the reduce motion setting in your operating system, reload the page, then hover the button, open the panel and send a short message. Chrome and Edge DevTools can emulate the setting for a single tab, but the operating system test is the more reliable check.