The "prefers-reduced-motion" media query

The "prefers-reduced-motion" media query

A media query aimed to those particularly sensitive to visual movements and animations.

Animations are great in web design. They can be cool, or they can be useful, or both! But they can easily become annoying or distracting. They could also create problems for people particularly sensitive to movements in their field of view.

Useful ways of using animations

Getting rid of the “cool” aspect, animations can be incredibly useful in giving feedback to the user: I'm thinking of a product image shrinking and moving over the shopping cart, or a message box fading away to suggest a dismissal, or a dropdown sliding down from its trigger to reinforce the perception of dependency of the first from the latter. In many cases, showing a clear path or movement reduces cognitive effort, off-loading it to the animation, freeing the user's logic and mnemonic resources for other operations.

Motion-triggered vestibular spectrum disorder

Some people find these animations as “distractions”, while others, unfortunately, don't have the luck of being able to choose: movements and animations can cause them nausea, motion sickness, migraines or even seizures. I'm talking about “vestibular disorders”, a broad term to describe any disease, damage, or injury to the “vestibular system”, a system that processes sensory information involved in controlling balance and eye movements.

Taking into account only those who have a chronic disorder (there are almost 20 different types of disorders) could be limiting, even if we're talking about 8 millions only in US, because exponentially greater numbers have at least experienced those disturbs. In addition, certain types of animations could potentially trigger also those with epilepsy and migraine sensitivities. Quite a huge number, isn't it?

What to consider in designing animations

Removing completely all sorts of animation could be counterproductive, but there is a need for a more aware use of interface animations. Different people experience different reactions to different conditions and stimuli, but three factors, in particular, are critical:

  • the relative size of the movement (objects moving across a large space),

  • the direction of movement (parallax and scrolljacking),

  • the perceived distance covered (a small distance, if in a 3d context, could be perceived as huge as far it gets).

How to design a responsible animation

  1. Be purposeful: have a reason for being there. Design your animation in a way that adds meaning to user interaction.

  2. Don't go "over the top": try to go easy with your animations. Do you need 10 rotations and a bouncing zoom to slide a panel outside?

  3. Give control to users: consider offering an option to turn off, or reduce, motion, potentially via a button or toggle switch. Or better... continue reading!

A little help from browsers?

Allowing a user to toggle animations is a great step towards certain categories of users, but it requires you to apply lots of JS code. And you should notify users the presence of animations and how to turn them off. And you should start with no animations at all. And you should... Wait, what about some kind of property that already knows if a user wants lesser animation when navigating the web?

Media Queries Level 5 allow to query values or features depending on user preferences. The media query prefers-reduced-motion is used to detect if the user has set an operating system preference to minimize the amount of animation/motionand it can take two values:

  • no-preference: Indicates that the user has made no preference in the operating system.

  • reduce: Indicates that the user has set a, OS preference indicating the intention of minimizing movement or animation, preferably to the point where all non-essential movement is removed.

@media (prefers-reduced-motion: reduce) {
    .animated-element {animation: none;}
}

And if you need to check the reduced motion via JS, you can use the following:

const reducedMotionMediaQuery = window.matchMedia('(prefers-reduced-motion: reduce)');
reducedMotionMediaQuery.addEventListener('change', () => {
    console.log(mediaQuery.media, mediaQuery.matches);
    // Do your logics and remove JavaScript-based animations.
});