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 Rafael Thayto 路 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.
- On macOS, open System Settings, go to Accessibility, then Display, and turn on the option for reducing motion.
- On Windows, open Settings, go to Accessibility, then Visual effects, and turn off animation effects.
- On iOS and Android, use the accessibility settings for motion or animations, and check the same screens on a phone.
- Load the page, hover the feedback button, open the panel, send a short message and check the success state.
- 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.
Related
- Feedback widget best practicesWhere to place a feedback button, how to keep it fast and accessible, and how to protect it from spam. Practical rules for in-app feedback widgets.
- What should a feedback button say?How to word a feedback button: verbs or nouns, labels that match each page and feedback type, localized copy, and how to replace the default Feedback button.
- Designing a feedback widget for mobile screensDesigning a feedback widget for phones: thumb reach, keyboard overlap, bottom navigation conflicts and the checks to run on a real device before you ship.
- How to make a feedback widget accessibleMake a feedback widget usable with a keyboard and screen reader: real buttons, dialog semantics, focus return, labels, contrast and known gaps.