Introduction
Great UI animation isn't about making things move — it's about making interfaces feel alive, responsive, and intuitive. Animation communicates state changes, guides attention, provides feedback, and creates spatial continuity.
The principles Disney animators developed — anticipation, follow-through, ease-in/ease-out — translate directly to digital interfaces.
This guide distills animation theory into practical principles you can apply to every interaction.
Key Concepts
Purpose-Driven Animation
Every animation should serve a purpose: feedback, guidance, relationships, or state indication. If an animation communicates nothing, remove it.
Timing and Duration
Micro-interactions: 100-200ms. State changes: 200-400ms. Orchestrations: 400-700ms. Nothing should exceed 1 second.
/* Micro-interactions: 100-200ms */
.button { transition: transform 0.15s ease; }
/* State changes: 200-400ms */
.panel { transition: transform 0.3s ease-out; }
/* Entrances longer than exits */
.modal-enter { animation: fadeIn 0.3s ease-out; }
.modal-exit { animation: fadeOut 0.2s ease-in; }
Easing
Ease-out for entering elements (arrive fast, settle slow). Ease-in for leaving (start slow, accelerate away). Ease-in-out for moving within viewport.
Practical Examples
1. Feedback Animation
.button:active { transform: scale(0.97); transition: transform 0.1s ease; }
@keyframes checkmark {
0% { stroke-dashoffset: 50; }
100% { stroke-dashoffset: 0; }
}
.success-check { stroke-dasharray: 50; animation: checkmark 0.4s ease-out forwards; }
2. Attention Guidance
@keyframes highlight {
0% { background: #fef3c7; }
100% { background: transparent; }
}
.new-item { animation: highlight 2s ease-out; }
3. Spatial Continuity
.drawer-right {
transform: translateX(100%);
transition: transform 0.3s ease-out;
}
.drawer-right.open { transform: translateX(0); }
4. Staggered Entrance
.card-grid > * {
opacity: 0; transform: translateY(20px);
animation: fadeInUp 0.4s ease-out forwards;
}
.card-grid > *:nth-child(1) { animation-delay: 0ms; }
.card-grid > *:nth-child(2) { animation-delay: 80ms; }
.card-grid > *:nth-child(3) { animation-delay: 160ms; }
Best Practices
- ✅ Every animation should have a clear purpose
- ✅ Keep micro-interactions under 200ms
- ✅ Use ease-out for entrances, ease-in for exits
- ✅ Animate from the direction of the trigger
- ✅ Respect prefers-reduced-motion
- ❌ Don't animate for decoration only
- ❌ Don't block interaction while animations complete
Common Pitfalls
- 🚫 Too slow — over 400ms feels sluggish
- 🚫 Too bouncy — excessive springs feel unprofessional
- 🚫 Inconsistent timing across similar actions
- 🚫 Animating when instant state change is better