Motion brings meaning and a sense of life to the experience.
#Principles
The principles of motion can vary, depending on the brand and style of an interface. However, there are a few generally applicable fundamentals to take into consideration.
#Predictable
Imagine throwing a ball into a hoop, and instead of it falling through — it just disappears!
As humans, we make sense of the world through interactions and observations around us. In real life, objects enter and leave our perception in a symmetrical and fluid movement.
Therefore, aim to maintain a consistent spatial understanding throughout the experience, similar to the real world.
#Purposeful
Strive to apply motion with an informative purpose by highlighting connections between elements, providing a focal point, or responding to an interaction with feedback.
Not only does this make the interface feel responsive and alive, but with the combination of predictable and purposeful motion, users can start to make sense of an interface and develop an intuition for future interactions.
#Playful
We've all experienced this one interaction that you can't stop playing with because it just feels right.
Motion can introduce a certain level of character and playfulness to seemingly common interactions and delight the user in an unexpected way.
Applying motion to an empty state, loading indicator, or a success screen is a great way to delight your users and celebrate their journey.
#Implementation
We can think of motion in three separate tiers:
#Tier A
The first tier of motion includes primitive CSS transitions and animations. These are mostly trivial to implement and don't require external animation libraries.
By responding to a hover interaction with a visual transition, users can anticipate an action.
A pulsing status indicator can be used to indicate an element that requires attention.
Responding to user input with a shake animation, referencing the physical gesture of someone shaking their head, can be an effective way to give feedback and provide focus.
#Tier B
The second tier of motion includes slightly more complicated entrance and exit animations.
Introducing motion for displaying elements on the screen is an excellent way to provide reassurance and meaning to interactions.
Elements appearing or disappearing instantly in response to an interaction create a visually and psychologically jarring experience.
It's a lot more pleasing, informative, and comforting to see the result in motion.
In addition to reinforcing the outcome of an action, motion can also establish a relationship between elements that are visually disconnected. Besides, it just looks cool!
iPhone SE RED — $399
Every iPhone SE RED purchase now contributes directly to the Global Fund to combat COVID-19.
For the most part, you can get pretty far with CSS animations. However, if you're using React and wish to have exit animations for components, you'll have to defer unmounting the component to finish the animation.
In this case, react-spring
or framer-motion
are great spring-physics based libraries for animating React components.
#Tier C
The third tier of motion includes SVG animations, loading indicators, and generally playful celebrations.
Using an animated SVG of your brand's logo is a fantastic way to express character and keep the user interested while loading content.
Skeleton loaders can be used to progressively load content while keeping the layout from jumping and the user engaged during slower connections.
#Animation duration
The duration of an animation can make the difference between a visually jarring animation and a pleasant one. Too fast, and it's distracting, too slow, and it feels like a delay.
In general, the duration should be in the range of 100-500ms, depending on the travel distance and how big the change is.
Responding to smaller changes, such as a checkbox toggle or button hover, should be roughly 100ms in duration. This feels almost immediate while still maintaining the sense of motion.
For bigger changes, such as notifications or modals, where elements are entering or exiting the screen, a duration of 200-300ms is suitable.
#Spring animations
If you're using React, we recommend checking out
react-spring
orframer-motion
for a spring-physics based animation library.
When working with CSS animations, you're probably used to thinking of motion in terms of durations and curves.
However, motion in general does not adhere to the concept of durations and curves, but rather physical properties such as mass and tension.
Think about it — if you were jumping on a trampoline with a specified duration of 500ms for each jump, but the jump gets interrupted half-way through, should the duration of the fall also be 500ms?
Moreover, working with spring animations means less tinkering with durations and curves. Just let physics take care of it.
Though, you don't have to use spring animations for every interaction. CSS works great for small interactions, such as hovers and toggles, where springs would likely mean additional complexity for little value.
#Accessibility
However playful and enjoyable an interaction may be, be mindful of the fact that not everybody can experience it the same way.
Some people may not consider motion to be an important part of their experience, and in some cases can even trigger physical reactions such as nausea and dizziness.
In most operating systems, users may opt out of motion from their accessibility settings. As a result, all of the native animations are disabled.
When implementing animations on the web, it is crucial to respect the choice of the user. The prefers-reduced-motion
media query works great for this:
.button {width: 100px;height: 40px;transform: scale(1);}.button:hover {transform: scale(1.2);}@media (prefers-reduced-motion: no-preference) {.button {transition: transform 300ms;}}
Instead of removing animations in the media query, default to no animations and add them for users who haven't explicitly opted out. This also means that if the browser does not support the query, it will just ignore it and not provide animations.
For Canvas and JS based animations, you can use window.matchMedia
to detect the user's preference:
const query = '(prefers-reduced-motion: no-preference)';const prefersReducedMotion = !window.matchMedia(query).matches;if (!prefersReducedMotion) {// Add animations!}