Animations and Micro-Interactions
Animation in user interfaces serves a purpose or it's noise. Good micro-interactions provide feedback, communicate state change, guide user attention, and smooth transitions. Bad animations delay the user, add cognitive load, and trigger motion sickness in susceptible users.
The principle: animation should enhance the experience, not decorate it. Every animation should answer "why is this animating?" If the answer is "it looks cool," reconsider.
When Animation Adds Value
- Communicates state change: A checkbox smoothly checks, a toggle smoothly switches. The animation shows the change happened.
- Provides feedback: Button press feels responsive with a slight scale or color change. Loading spinner indicates work is happening.
- Guides attention: A new notification slides in with animation, drawing the eye. Without it, you might miss it.
- Smooths transitions: Fading between pages is better than an instant cut—it orients the user to the change.
- Explains interaction: A menu animating open shows how the interface changed. An item morphing from one shape to another explains the connection.
When Animation Becomes Noise
- Purely decorative: A bouncing background, a spinning loading icon when a simple dot animation works, animations that don't communicate anything.
- Slow: An animation that takes 2 seconds when 300ms would accomplish the same thing delays the user without benefit.
- Blocking: Animations that prevent user interaction ("wait for the transition to finish before you can click"). Users want to act, not watch.
- Disorienting: Excessive parallax, spinning, or zooming effects that make navigation confusing.
CSS Transitions: Simple and Performant
CSS transitions are the right tool for most UI animations. Changing from one state to another (hover state, focus state, active state) with a smooth transition is simple:
button {
background: blue;
transition: background 200ms ease-in-out;
}
button:hover {
background: darkblue;
}
CSS transitions are performant because the browser can optimize them (GPU acceleration). They don't require JavaScript. They're simple.
CSS Keyframes: More Complex Animations
Keyframe animations define multiple steps. A loading spinner spinning, a message sliding in and fading out, a notification appearing and disappearing. Pure CSS, no JavaScript required.
Keyframes are performant when animating the right properties. CSS transforms (translate, scale, rotate) and opacity are GPU-accelerated and smooth. Avoid animating width, height, top, left, or margin—these require layout recalculation and are slow.
Framer Motion: React-Specific Animation Library
Framer Motion is a React animation library that makes complex animations declarative. It handles timing, easing, spring physics, and layout animations elegantly.
Use Framer Motion when CSS isn't sufficient: complex state-based animations, gesture-driven animations (swipe to dismiss), coordinated multi-element animations. Framer Motion's strength is making complex animations feel natural with spring physics.
Framer Motion is not a replacement for CSS transitions—use CSS for simple state changes, Framer Motion for complex animations.
GSAP: Powerful Cross-Framework Library
GSAP (GreenSock Animation Platform) is a powerful animation library that works with any framework. It's the industry standard for complex timeline animations, coordinated animations, and animations triggered by scrolling.
GSAP is overkill for simple animations but indispensable for complex ones. It has excellent performance, browser support, and capabilities. However, it's not lightweight, so only use it if you have animation requirements that justify the bundle size.
Performance: Animating the Right Properties
Not all animations are equal. Animating transform (translate, scale, rotate) and opacity is GPU-accelerated and smooth. Animating width, height, top, left, or margin causes layout recalculation and is slow.
To move an element, don't change left or top—use transform: translateX() or translateY(). To resize, consider using transform: scale(). These transform-based approaches are dramatically faster.
Avoid animating box-shadow, border-radius, or filter properties—they're expensive. If you must, animate sparingly (small number of elements) and test on slower devices.
Respecting User Preferences: prefers-reduced-motion
Some users have motion sensitivity or vestibular disorders. Excessive animation makes them nauseous or disoriented. Respect the prefers-reduced-motion media query:
@media (prefers-reduced-motion: reduce) {
* {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}
When prefers-reduced-motion is set, disable animations or make them instant. This is not optional—it's accessibility. Users who set this preference have a real physical reaction to motion. Ignoring it excludes them.
Loading States and Feedback
Loading indicators communicate that work is happening. A spinner, a progress bar, or a skeleton screen. Without it, the user thinks the page is broken.
For very short operations (under 100ms), don't show a loader—the UI update will feel instant. For operations 100-500ms, show a simple loader. For longer operations, show progress if possible (progress bar), or a message ("this might take a minute").
Success and error states should be obvious. A green checkmark, a red X, a toast message. Make the result of the action clear.
Transitioning Between Pages
When navigating to a new page, a brief fade or slide transition helps the user understand the page changed. Without transition, it feels jarring. With too much transition, it feels slow.
A 200-300ms fade transition is usually right. Avoid long transitions that block the user from interacting with the new page.
When to Say No
Designers sometimes request animations that look good in a prototype but hurt user experience. Animations that:
- Delay interaction (user waits for animation to finish to interact)
- Are purely decorative with no functional purpose
- Add complexity that doesn't match benefit
- Trigger motion sensitivity issues
These should be pushed back on. "This animation looks cool but delays the user. Let's skip it." Frame it as respecting the user's time, not rejecting the designer's work.
The Principle
Every animation should serve a purpose. If you can't articulate why an animation exists, it probably shouldn't. Animation is a powerful tool for communication, but it's easy to misuse. Restrain yourself. Animation that matters is animation that's intentional.