Renderizado do repositório de origem, preservando títulos, exemplos, código, tabelas, links e imagens.
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 58 rules across 8 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
- Expressing any of the above with Tailwind CSS v4 utilities (see the
tw-category)
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- |
| 8 | Tailwind v4 Utilities | MEDIUM | tw- |
Quick Reference
1. 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-spring-config` - Configure springs with duration and bounce
- `ease-ios-drawer` - Use iOS-style easing for drawer components
- `ease-context-matters` - Match easing to animation context
2. 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
3. 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
4. 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
- `transform-starting-style` - Animate enter states with @starting-style
5. 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
- `interact-multitouch` - Ignore extra touch points during drag
- `interact-touch-hover` - Gate hover animations behind a pointer media query
6. 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
- `strategy-cohesion` - Match motion to the component's personality
- `strategy-review-fresh-eyes` - Review animations in slow motion and the next day
7. 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` - Keep gentle 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
8. Tailwind v4 Utilities (MEDIUM)
Express the principles above with proper Tailwind CSS v4 utilities. Applies only to Tailwind v4 projects; the raw-CSS and Framer Motion rules above remain the source of truth.
- `tw-ease-duration-defaults` - Set ease-out and a sub-300ms duration explicitly
- `tw-custom-easing-theme` - Register custom easing curves as @theme tokens
- `tw-press-scale` - Use active:scale-[0.97] for button press feedback
- `tw-asymmetric-timing` - Split press and release timing with active:duration
- `tw-starting-enter` - Animate enter states with the starting: variant
- `tw-reduced-motion` - Gate movement behind motion-safe / motion-reduce
- `tw-origin-aware` - Set transform-origin with origin-* utilities
- `tw-will-change` - Scope will-change-transform to the active gesture
Key Values Reference
| Value | Usage |
|---|---|
cubic-bezier(0.23, 1, 0.32, 1) | Strong ease-out for UI interactions |
cubic-bezier(0.77, 0, 0.175, 1) | Strong ease-in-out for on-screen movement |
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 |
Duration by Element
Pick duration by how often the element is seen and how much it moves. Keep UI animations under 300ms.
| Element | Duration |
|---|---|
| Button press feedback | 100–160ms |
| Tooltips, small popovers | 125–200ms |
| Dropdowns, selects | 150–250ms |
| Modals, drawers | 200–500ms |
| Marketing / explanatory | Can be longer |
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 |

