Return to site
Goodbye @angular/animations — hello animate.enter & animate.leave in Angular 20.2 🎯
Goodbye @angular/animations — hello animate.enter & animate.leave in Angular 20.2 🎯
·
TL;DR — Starting with Angular 20.2, the @angular/animations package is deprecated. Instead, you animate directly from templates using two new features: animate.enter and animate.leave. It’s simpler, lighter, and leverages native CSS or your favorite JS animation library.
Why this change?
- Simpler DX: No framework-specific DSL—just HTML + CSS (or a JS library).
- Smaller bundles: Removing @angular/animations can significantly reduce JS size.
- Smooth performance: Use GPU-friendly CSS transitions/animations.
What the new features do (in a nutshell)
- animate.enter="classA classB" → Applies CSS class(es) when an element enters the DOM.
- animate.leave="classC" → Applies class(es) when an element leaves; Angular removes the node after the longest transition/animation ends.
- (animate.leave)="onLeave($event)" → Run your own JS animation (Web Animations API, GSAP, etc.), then call $event.animationComplete() so Angular knows it can remove the element. (If you forget, Angular times out after ~4s; configurable via MAX_ANIMATION_TIMEOUT.)
Tiny examples
Enter (CSS keyframes):
@if (isShown()) { <div class="card" animate.enter="fade-in">Content</div> }
.fade-in { animation: slide-fade 300ms ease-out both; } @keyframes slide-fade { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
Leave (CSS transitions):
@if (isShown()) { <div class="card" animate.leave="fade-out">Bye 👋</div> }
.fade-out { opacity: 0; transform: translateY(8px); transition: opacity 200ms, transform 200ms; }
Angular removes the element after the transition finishes.
Leave (JS-driven):
<div (animate.leave)="onLeave($event)">JS-animated leave</div>onLeave(event: any) { const el: HTMLElement = event.target; const anim = el.animate( [{ opacity: 1, transform: 'translateY(0)' }, { opacity: 0, transform: 'translateY(10px)' }], { duration: 280, easing: 'ease-out', fill: 'forwards' } ); anim.addEventListener('finish', () => event.animationComplete()); }
(Calling animationComplete() is required when you take over the leave animation.)
Migration in 4 quick steps
- Inventory your existing triggers/DSL (trigger, transition, state, :enter, :leave).
- Re-implement with CSS classes + animate.enter / animate.leave in templates.
- For any JS choreography, switch to (animate.leave) with animationComplete().
- Remove @angular/animations once deps are updated.
Downloadable demo app (with code comments)
- What’s inside: three examples—CSS keyframes on enter, CSS transitions on leave, and a Web Animations API leave with animationComplete().
- Run it
👉 Download the project zip 👇
Official references
- Enter/Leave guide — how it works, event bindings, animationComplete(), and MAX_ANIMATION_TIMEOUT.
- Migration guide — deprecation of @angular/animations in v20.2 + why CSS/JS is recommended.
- CSS animations guide — patterns and tips for native CSS animations.