There's been enough discussion on the value of animation in interfaces. Good and bad examples aside, I hope we're at a point now where we can recognise its importance and function. Amongst this noise however, a group of users with a physical aversion to motion are being quietly under-represented.
I’ve been focusing on accessible and inclusive patterns in my frontend work and I’ve recently read some great articles on reduced motion queries. James, Eric, Chris and Hugo do a great job of giving context, tips and justification for the feature, and discuss the topic far more eloquently than I ever could so I'll wait here while you quickly brush up before I share my experiences.
A note before I go on: My decision to add support for reduced motion was made after I’d finished a recent build, Landscape Elements. I didn't want to spend too much more time on an already over budget project, so in some ways this is evidence that accessibility gains don't have to be an expensive exercise.
If you’re playing along at home, open your system preferences and select Reduced motion in the Accessibility tab, then fire up the most recent release of Safari. Browser support is patchy for now but looking promising for the future.
(Sometimes) quick and dirty ≠ bad
I strive for elegance when coding, at the outset of each project promising myself that this will be my pièce de résistance, my hack-free masterpiece. Yet much like achieving nirvana this goal I'm afraid will be a lifelong pursuit. Sometimes we just need to compromise with a quick and/or dirty solution.
To begin, I attempted to override EVERYTHING that moved with as little effort as possible.
This actually got me pretty far but elements that relied on
transform for positioning were not behaving. 😢
A slight iteration and phew, transform controlled layout is looking better and most of the previously animated UI is now static. Even animation from third-parties like Slick Slider and Isotope were now under control. Win!
P.S. I actually think
!important has its place in the css ecosystem. 🙊 The cascade is great but sometimes you need to sidestep it quickly!
☝️ I’m using a
Window.matchMedia() query here to exclude a js for animation when the users opts for reduced motion. It feels a bit progressive-enhancy or something that way.
Allowing for granular control
The last thing I needed was a way to control animation in more bespoke circumstances.
Window.matchMedia() again, I added a class to flag that the user has specified reduced motion.
.prefers-no-motionas a nested parent selector allowed me to target and minimise instances of transform based motion on specific elements at a component level. (At this point I thought to myself "I'd probably be closer to nirvana if I wrote reduced motion first css..." Oh well, maybe next time eh?)
Everybody's doing a brand-new dance, now
Here ends my initial experiments with reduced motion queries. I’m curious to see your implementations so please feel free to get in touch and share them. I’m not sure there is a correct approach and in most cases it’s probably a best fit solution that will get you over the line.
I'm interested in the concepts in Hugo’s article that I mentioned earlier, especially leveraging CSS custom properties. I think with some planning on my next build I’ll have a bash at something similar but for now quick and dirty suits me fine.
If nothing else, let this post be our reminder that accessibility shouldn't be an afterthought and also to point out that User Preference Media Features are damn cool.
Oh and I wrote you two lines of a song.
Everybody's doing a brand-new dance, now.
Come on baby, code for ‘prefers-reduced-motion’.