Return to site

Goodbye @angular/animations — hello animate.enter & animate.leave in Angular 20.2 🎯

· angular

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

  1. Inventory your existing triggers/DSL (trigger, transition, state, :enter, :leave).
  2. Re-implement with CSS classes + animate.enter / animate.leave in templates.
  3. For any JS choreography, switch to (animate.leave) with animationComplete().
  4. 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