Skip to content
How to use motion in an accessible way.

Motion can trigger discomfort for people with vestibular motion disorders. Animations such as scaling or panning large objects can be vestibular motion triggers. According to vestibular.org, 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 if you'd like to learn more about this.

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.

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

.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;
    }
}
Information:

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.

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

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,
            }}
        />
    )
}

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 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.

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.