# Motion

How to use motion in an accessible way.

Tabs: [Overview](/foundations/motion/motion.overview.md) · [About](/foundations/motion/motion.about.md) · [Design](/foundations/motion/motion.design.md) · [Accessibility](/foundations/motion/motion.accessibility.md) · [Resources](/foundations/motion/motion.resources.md)

## Reduced motion

Motion can trigger discomfort for people with [vestibular motion disorders](https://www.a11yproject.com/posts/understanding-vestibular-disorders/). Animations such as scaling or panning large objects can be vestibular motion triggers. According to [vestibular.org](https://vestibular.org/article/what-is-vestibular/about-vestibular-disorders/#view-references), as many as 35% of adults aged 40 years or older in the United States have experienced some form of vestibular dysfunction.

As such, all animations which could be vestibular triggers should respect the `prefers-reduced-motion` user preference. You can find links to articles and documentation around reduced motion in [the resources section](/foundations/motion/motion.resources) if you'd like to learn more about this.

## Implementation

How you handle `prefers-reduced-motion` depends on the technology you're using to implement motion. There are a couple of examples below, but you can find more information in [the resources section](/foundations/motion/motion.resources).

### CSS animations

When using CSS transitions or animations, you can use the `prefers-reduced-motion` media query to *opt in* to animations. For example:

```css
.fancy-box {
    width: 100px;
    height: 100px;
    transform: scale(1);
}

.fancy-box:hover {
    transform: scale(1.2);
}

@media (prefers-reduced-motion: no-preference) {
    .fancy-box {
        transition: transform 300ms;
    }
}
```

> `no-preference` is the default value for the `prefers-reduced-motion` media query. This means that if the user hasn't set a preference (or has explicitly allowed motion), the transition will be enabled.

### Motion animations

Motion exposes a `useReducedMotion` hook that you can use to disable animations when `prefers-reduced-motion` is set. For example:

```tsx
export function Sidebar({isOpen}: {isOpen: boolean}) {
    const shouldReduceMotion = useReducedMotion()
    const closedX = shouldReduceMotion ? 0 : '-100%'

    return (
        <motion.div
            animate={{
                opacity: isOpen ? 1 : 0,
                x: isOpen ? 0 : closedX,
            }}
        />
    )
}
```

## Types of motion to avoid when `prefers-reduced-motion` is set

Scale, zoom, spinning or positional animations can be particularly problematic for users with vestibular disorders. These should be avoided or replaced with opacity fades.

We should also avoid flickering or blinking animations. These can be distracting, and in some cases can trigger epileptic episodes.

Colour transitions and opacity fades tend not to be vestibular triggers, so something like transitioning the background colour of an element on hover is generally safe. Furthermore, opacity fades are often a good replacement for animations that are vestibular triggers when `prefers-reduced-motion` is set. For example, when opening a [Drawer](/components/web/drawer/drawer.guidelines) component, we fade the Drawer in and out rather than sliding it in from the side of the screen. This ensures users still get the benefits of motion when opening a Drawer, but in a way that is less likely to trigger vestibular discomfort.

## Testing reduced motion

You can test reduced motion animations either by emulating the `prefers-reduced-motion` media query in your browser's developer tools, or by setting it at the operating system level. You can learn more about how to emulate this in your browser by following the guide in the [Google Chrome documentation](https://developer.chrome.com/docs/devtools/rendering/emulate-css#emulate_css_media_feature_prefers-reduced-motion).
