Emil Kowalski Animation Best Practices
Comprehensive animation guide for web interfaces based on Emil Kowalski's teachings, open-source libraries (Sonner, Vaul), and his animations.dev course. Contains 43 rules across 7 categories, prioritized by impact.
When to Apply
Reference these guidelines when:
-
Adding animations to React components
-
Choosing easing curves or timing values
-
Implementing gesture-based interactions (swipe, drag)
-
Building toast notifications or drawer components
-
Optimizing animation performance
-
Ensuring animation accessibility
Rule Categories by Priority
Priority Category Impact Prefix
1 Easing Selection CRITICAL ease-
2 Timing & Duration CRITICAL timing-
3 Property Selection HIGH props-
4 Transform Techniques HIGH transform-
5 Interaction Patterns MEDIUM-HIGH interact-
6 Strategic Animation MEDIUM strategy-
7 Accessibility & Polish MEDIUM polish-
Quick Reference
- Easing Selection (CRITICAL)
-
ease-out-default
-
Use ease-out as your default easing
-
ease-custom-curves
-
Use custom cubic-bezier over built-in CSS
-
ease-in-out-onscreen
-
Use ease-in-out for on-screen movement
-
ease-spring-natural
-
Use spring animations for natural motion
-
ease-ios-drawer
-
Use iOS-style easing for drawer components
-
ease-context-matters
-
Match easing to animation context
- Timing & Duration (CRITICAL)
-
timing-300ms-max
-
Keep UI animations under 300ms
-
timing-faster-better
-
Faster animations improve perceived performance
-
timing-asymmetric
-
Use asymmetric timing for press and release
-
timing-tooltip-delay
-
Delay initial tooltips, instant subsequent ones
-
timing-drawer-500ms
-
Use 500ms duration for drawer animations
- Property Selection (HIGH)
-
props-transform-opacity
-
Animate only transform and opacity
-
props-hardware-accelerated
-
Use hardware-accelerated animations when main thread is busy
-
props-will-change
-
Use will-change to prevent 1px shift
-
props-avoid-css-variables
-
Avoid CSS variables for drag animations
-
props-clip-path-performant
-
Use clip-path for layout-free reveals
- Transform Techniques (HIGH)
-
transform-scale-097
-
Scale buttons to 0.97 on press
-
transform-never-scale-zero
-
Never animate from scale(0)
-
transform-percentage-translate
-
Use percentage values for translateY
-
transform-origin-aware
-
Make animations origin-aware
-
transform-scale-children
-
Scale transforms affect children
-
transform-3d-preserve
-
Use preserve-3d for 3D transform effects
- Interaction Patterns (MEDIUM-HIGH)
-
interact-interruptible
-
Make animations interruptible
-
interact-momentum-dismiss
-
Use momentum-based dismissal
-
interact-damping
-
Damp drag at boundaries
-
interact-scroll-drag-conflict
-
Resolve scroll and drag conflicts
-
interact-snap-points
-
Implement velocity-aware snap points
-
interact-friction-upward
-
Allow upward drag with friction
-
interact-pointer-capture
-
Use pointer capture for drag operations
- Strategic Animation (MEDIUM)
-
strategy-keyboard-no-animate
-
Never animate keyboard-initiated actions
-
strategy-frequency-matters
-
Consider interaction frequency before animating
-
strategy-purpose-required
-
Every animation must have a purpose
-
strategy-feedback-immediate
-
Provide immediate feedback on all actions
-
strategy-marketing-exception
-
Marketing sites are the exception
- Accessibility & Polish (MEDIUM)
-
polish-reduced-motion
-
Respect prefers-reduced-motion
-
polish-opacity-fallback
-
Use opacity as reduced motion fallback
-
polish-framer-hook
-
Use useReducedMotion hook in Framer Motion
-
polish-dont-remove-all
-
Don't remove all animation for reduced motion
-
polish-blur-bridge
-
Use blur to bridge animation states
-
polish-clip-path-tabs
-
Use clip-path for tab transitions
-
polish-toast-stacking
-
Implement toast stacking with scale and offset
-
polish-scroll-reveal
-
Trigger scroll animations at appropriate threshold
-
polish-hover-gap-fill
-
Fill gaps between hoverable elements
-
polish-stagger-children
-
Stagger child animations for orchestration
Key Values Reference
Value Usage
cubic-bezier(0.32, 0.72, 0, 1)
iOS-style drawer/sheet animation
scale(0.97)
Button press feedback
scale(0.95)
Minimum enter scale (never scale(0))
200ms ease-out
Standard UI transition
300ms
Maximum duration for UI animations
500ms
Drawer animation duration
0.11 px/ms
Velocity threshold for momentum dismiss
100px
Scroll-reveal viewport threshold
14px
Toast stack offset
Reference Files
File Description
references/_sections.md Category definitions and ordering
assets/templates/_template.md Template for new rules
metadata.json Version and reference information