There is a code snippet that I see all the time when the media query prefers-reduced-motion
is talked about. Here it is:
@media (prefers-reduced-motion: reduce) {
* {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
}
This is CSS that attempts to obliterate any motion on a website under the condition that the user has specified a preference for reduced motion in the accessibility preferences of their operating system.
prefers-reduced-motion
matters
Why The reason this setting exists is that on-screen movement is an accessibility concern. Here’s Eric Bailey:
Vestibular disorders can cause your vestibular system to struggle to make sense of what is happening, resulting in loss of balance and vertigo, migraines, nausea, and hearing loss. Anyone who has spun around too quickly is familiar with a confused vestibular system.
Vestibular disorders can be caused by both genetic and environmental factors. It’s part of the larger spectrum of conditions that make up accessibility concerns and it affects more than 70 million people.
Here he is again in a follow-up article:
If you have a vestibular disorder or have certain kinds of migraine or seizure triggers, navigating the web can be a lot like walking through a minefield — you’re perpetually one click away from activating an unannounced animation. And that’s just for casual browsing.
Reduced motion vs. nuked motion
Knowing this, the temptation might be high to go nuclear on the motion and wipe it out entirely when a user has specified a reduced motion preference. The trouble with that is — to quote Eric again — “animation isn’t unnecessary.” Some of it might be, but animation can also help accessibility. For example, a “transitional interface” (e.g. a list that animates an opening for a new item to slide into it) can be very helpful:
Animation can be a great tool to help combat some forms of cognitive disability by using it to break down complicated concepts, or communicate the relationship between seemingly disparate objects. Val Head’s article on A List Apart highlights some other very well-researched benefits, including helping to increase problem-solving ability, recall, and skill acquisition, as well as reducing cognitive load and your susceptibility to change blindness.
In this case, you would lose the helpful contextual movement if you just nuked it all. You just might want to take a different approach when in a prefers-reduced-motion
scenario. Perhaps less, slower, or removed motion while leaning harder on color and fading transitions.
Ban Nadel recently wrote “Applying Multiple Animation @keyframes To Support Prefers-Reduced-Motion In CSS” and covered a similar example. A modal entrance animation uses both a fade-in and scale-in effect by default. Then, in a prefers-reduced-motion
scenario, it uses the fade-in but not the scaling. The scaling causes movement in a way the fading doesn’t.
/*
By default, we'll use the REDUCED MOTION version of the animation.
*/
@keyframes modal-enter {
from {
opacity: 0 ;
}
to {
opacity: 1 ;
}
}
/*
Then, if the user has NO PREFERENCE for motion, we can OVERRIDE the
animation definition to include both the motion and non-motion properties.
*/
@media ( prefers-reduced-motion: no-preference ) {
@keyframes modal-enter {
from {
opacity: 0 ;
transform: scale(0.7) ;
}
to {
opacity: 1 ;
transform: scale(1.0) ;
}
}
}
See the GIF demo on Ben’s site if you’d like to see a quick comparison.
I like how this style of approach is think about the problem and come up with a reduced motion solution, rather than screw it all, no movement period!!
But not all motion is driven by CSS
While we’re on the topic of that screw-all-motion CSS snippet, note that it’s only effective at doing what it sets out to do on sites where all the movement is entirely CSS-driven. If you’re using JavaScript-powered animations beware that this nuclear snippet might… well here’s Josh Comeau:
If your animations are entirely driven by CSS, this works great… But I’ve had weird issues when running animations in JS. Specifically, I’ve seen this reset have the opposite effect, and make animations super fast and dizzying.
That’s right: It might do quite literally the opposite of what you are trying to do.
Animated images need to be considered as well. Solving that may require altering the HTML, not only the CSS
I don’t mean to knit pick, but Josh Cameau’s article simply made the point that devs need to be mindful of how motion is implemented, not that the media query is unreliable.
Basically, build in a way to read the user’s preferences and have the app act accordingly, which Cameau’s article illustrates.
I’m only pointing out the distinction because this article reads as a bit of a table flip at the end. Again, it’s okay to use motion, just make sure you build in an escape hatch via the media query.
I agree that the all or nothing approach, while it simplifies engineering, is certainly heavy handed.
I’d appreciate more information on the animation levels which trigger vestibular disorder.
There must be a difference between large scrolling banners and small animated icons?
On the JS side of things, remember there’s also .matchMedia() !!!