@angular/animations
The Angular animations package provides a powerful, declarative API for creating sophisticated animations in your Angular applications. Built on top of the Web Animations API, it offers fine-grained control over timing, styles, and complex animation sequences.
Overview
Angular animations enable you to define how HTML elements move, change appearance, and transition between states. The animation system integrates seamlessly with Angular’s component model and change detection.
Web Standards Based Angular animations are built on the Web Animations API, providing high-performance animations that run efficiently in modern browsers.
Installation
npm install @angular/animations
Quick Start
1. Import the Module
Add BrowserAnimationsModule to your application:
import { provideAnimations } from '@angular/animations/browser' ;
export const appConfig : ApplicationConfig = {
providers: [
provideAnimations (),
// ... other providers
]
};
2. Define an Animation
Create animation triggers in your component:
import { Component } from '@angular/core' ;
import { trigger , state , style , transition , animate } from '@angular/animations' ;
@ Component ({
selector: 'app-example' ,
template: `
<div [@fadeIn]="isVisible ? 'visible' : 'hidden'">
Hello, Animations!
</div>
` ,
animations: [
trigger ( 'fadeIn' , [
state ( 'hidden' , style ({ opacity: 0 })),
state ( 'visible' , style ({ opacity: 1 })),
transition ( 'hidden => visible' , animate ( '300ms ease-in' )),
transition ( 'visible => hidden' , animate ( '300ms ease-out' ))
])
]
})
export class ExampleComponent {
isVisible = true ;
}
3. Bind to Template
Attach animations using the [@triggerName] syntax:
< div [@fadeIn] = "animationState" > Content </ div >
< button [@buttonState] = "state" (click) = "toggle()" > Click me </ button >
Core Concepts
Animation Triggers
Triggers define named animations that can be bound to elements:
Creates a named animation trigger trigger ( 'myAnimation' , [
// animation steps
])
Unique name for the animation trigger
definitions
AnimationMetadata[]
required
Array of animation states and transitions
States
Define the appearance of an element in different states:
state ( 'inactive' , style ({
backgroundColor: '#eee' ,
transform: 'scale(1)'
}))
state ( 'active' , style ({
backgroundColor: '#007bff' ,
transform: 'scale(1.1)'
}))
Use the wildcard state * to match any state, or void to represent an element entering or leaving the DOM.
Transitions
Define how elements animate between states:
// Specific state change
transition ( 'inactive => active' , animate ( '300ms' ))
// Bidirectional
transition ( 'inactive <=> active' , animate ( '300ms' ))
// Any state change
transition ( '* => *' , animate ( '300ms' ))
// Entering the DOM
transition ( ':enter' , [
style ({ opacity: 0 }),
animate ( '500ms' , style ({ opacity: 1 }))
])
// Leaving the DOM
transition ( ':leave' , [
animate ( '500ms' , style ({ opacity: 0 }))
])
Styles
Define CSS properties for animation states:
style ({
opacity: 0 ,
transform: 'translateX(-100%)' ,
backgroundColor: '#f0f0f0'
})
Use '*' or the special AUTO_STYLE constant to let Angular compute the value automatically.
Animation Functions
animate()
Specifies timing and styles for an animation step:
Simple Duration
With Easing
With Delay
With Styles
Timing Format: duration delay easing
duration : Time in ms or s (e.g., '300ms', '0.3s')
delay : Optional delay before starting
easing : Easing function (ease, ease-in, ease-out, ease-in-out, linear, cubic-bezier(...))
sequence()
Runs animation steps one after another:
sequence ([
animate ( '200ms' , style ({ opacity: 0.5 })),
animate ( '300ms' , style ({ transform: 'translateY(100px)' })),
animate ( '200ms' , style ({ opacity: 1 }))
])
group()
Runs animation steps in parallel:
group ([
animate ( '300ms' , style ({ transform: 'translateX(100px)' })),
animate ( '300ms' , style ({ opacity: 0.5 })),
animate ( '300ms' , style ({ backgroundColor: 'red' }))
])
keyframes()
Define animation keyframes for more complex sequences:
animate ( '1s' , keyframes ([
style ({ opacity: 0 , transform: 'translateX(-100%)' , offset: 0 }),
style ({ opacity: 0.5 , transform: 'translateX(-50px)' , offset: 0.3 }),
style ({ opacity: 1 , transform: 'translateX(0)' , offset: 1.0 })
]))
The offset property (0 to 1) specifies when each keyframe occurs during the animation.
query()
Query child elements to animate them:
query ( '.item' , [
animate ( '300ms' , style ({ opacity: 0 }))
])
// Query multiple elements
query ( ':enter' , [
stagger ( '100ms' , [
animate ( '300ms' , style ({ opacity: 1 }))
])
])
Query Selectors:
.className - Elements with class
#id - Element with ID
:enter - Elements entering the DOM
:leave - Elements leaving the DOM
:animating - Currently animating elements
@triggerName - Elements with trigger
* - All elements
stagger()
Create staggered animations for lists:
query ( '.list-item' , [
stagger ( '100ms' , [
animate ( '300ms ease-out' , style ({ opacity: 1 , transform: 'translateY(0)' }))
])
])
animateChild()
Trigger child animations explicitly:
transition ( '* => *' , [
query ( '@childAnimation' , [
animateChild ()
])
])
Common Animation Patterns
Fade In/Out
transition ( ':enter' , [
style ({ opacity: 0 }),
animate ( '300ms' , style ({ opacity: 1 }))
])
Slide In/Out
trigger ( 'slide' , [
transition ( ':enter' , [
style ({ transform: 'translateX(-100%)' }),
animate ( '300ms ease-out' , style ({ transform: 'translateX(0)' }))
]),
transition ( ':leave' , [
animate ( '300ms ease-in' , style ({ transform: 'translateX(100%)' }))
])
])
Scale/Zoom
trigger ( 'zoom' , [
transition ( ':enter' , [
style ({ transform: 'scale(0)' , opacity: 0 }),
animate ( '300ms cubic-bezier(0.68, -0.55, 0.265, 1.55)' ,
style ({ transform: 'scale(1)' , opacity: 1 })
)
])
])
Rotate
trigger ( 'rotate' , [
state ( 'default' , style ({ transform: 'rotate(0)' })),
state ( 'rotated' , style ({ transform: 'rotate(360deg)' })),
transition ( 'default <=> rotated' , animate ( '500ms ease-in-out' ))
])
List Animations
trigger ( 'listAnimation' , [
transition ( '* => *' , [
query ( ':enter' , [
style ({ opacity: 0 , transform: 'translateY(-15px)' }),
stagger ( '50ms' , [
animate ( '300ms ease-out' ,
style ({ opacity: 1 , transform: 'translateY(0)' })
)
])
], { optional: true }),
query ( ':leave' , [
stagger ( '50ms' , [
animate ( '300ms ease-in' ,
style ({ opacity: 0 , transform: 'translateY(-15px)' })
)
])
], { optional: true })
])
])
Advanced Features
Reusable Animations
Create reusable animation definitions:
import { animation , style , animate , trigger } from '@angular/animations' ;
// Define reusable animation
export const fadeIn = animation ([
style ({ opacity: 0 }),
animate ( '{{ duration }}' , style ({ opacity: 1 }))
]);
// Use with useAnimation()
trigger ( 'fadeInTrigger' , [
transition ( ':enter' , [
useAnimation ( fadeIn , {
params: { duration: '300ms' }
})
])
])
Animation Callbacks
Listen to animation events:
@ Component ({
template: `
<div [@fadeIn]="state"
(@fadeIn.start)="onAnimationStart($event)"
(@fadeIn.done)="onAnimationDone($event)">
Content
</div>
`
})
export class MyComponent {
onAnimationStart ( event : AnimationEvent ) {
console . log ( 'Animation started' , event );
}
onAnimationDone ( event : AnimationEvent ) {
console . log ( 'Animation completed' , event );
}
}
Animation lifecycle event The state the element is transitioning from
The state the element is transitioning to
Total animation time in milliseconds
Animation lifecycle phase
Name of the animation trigger
Animation Parameters
Pass parameters to animations:
trigger ( 'dynamicAnimation' , [
transition ( '* => *' , [
animate ( '{{ duration }} {{ easing }}' ,
style ({
transform: 'translateX({{ distance }})' ,
backgroundColor: '{{ color }}'
})
)
])
])
// In template
< div [@ dynamicAnimation ] = " {
value : animationState ,
params : {
duration : '500ms' ,
easing : 'ease-in-out' ,
distance : '100px' ,
color : '#007bff'
}
} " >
Programmatic Animations
Use AnimationBuilder for runtime control:
import { AnimationBuilder , style , animate } from '@angular/animations' ;
constructor ( private builder : AnimationBuilder ) {}
playAnimation ( element : ElementRef ) {
const factory = this . builder . build ([
style ({ opacity: 0 }),
animate ( '500ms' , style ({ opacity: 1 }))
]);
const player = factory . create ( element . nativeElement );
player . play ();
}
Programmatic animation builder Creates an animation factory from metadata build ( animation : AnimationMetadata | AnimationMetadata []): AnimationFactory
Controls animation playback
Route Animations
Animate navigation between routes:
export const routeAnimations = trigger ( 'routeAnimations' , [
transition ( 'HomePage <=> AboutPage' , [
style ({ position: 'relative' }),
query ( ':enter, :leave' , [
style ({
position: 'absolute' ,
top: 0 ,
left: 0 ,
width: '100%'
})
], { optional: true }),
query ( ':enter' , [
style ({ left: '-100%' })
], { optional: true }),
query ( ':leave' , animateChild (), { optional: true }),
group ([
query ( ':leave' , [
animate ( '300ms ease-out' , style ({ left: '100%' }))
], { optional: true }),
query ( ':enter' , [
animate ( '300ms ease-out' , style ({ left: '0%' }))
], { optional: true })
]),
query ( ':enter' , animateChild (), { optional: true })
])
]);
@ Component ({
template: `
<div [@routeAnimations]="getRouteAnimationData()">
<router-outlet />
</div>
` ,
animations: [ routeAnimations ]
})
export class AppComponent {
getRouteAnimationData () {
// Return route data for animation state
}
}
Use transform & opacity Animate transform and opacity for GPU acceleration. Avoid animating width, height, top, or left.
Disable animations Use NoopAnimationsModule in tests or for users who prefer reduced motion
Query options Use { optional: true } in queries to prevent errors when elements don’t exist
Clean up Animations clean up automatically, but call destroy() on manual players
Disable Animations
import { provideNoopAnimations } from '@angular/animations/browser' ;
export const appConfig : ApplicationConfig = {
providers: [
provideNoopAnimations (), // Disables all animations
]
};
Respect User Preferences
@ media ( prefers - reduced - motion : reduce ) {
* {
animation- duration: 0.01 ms ! important ;
animation - iteration - count : 1 ! important ;
transition - duration : 0.01 ms ! important ;
}
}
API Reference
Core Functions
Creates a named animation trigger trigger ( name : string , definitions : AnimationMetadata []): AnimationTriggerMetadata
Defines a named state with styles state ( name : string , styles : AnimationStyleMetadata , options ?: AnimationOptions ): AnimationStateMetadata
Defines a transition between states transition ( stateChangeExpr : string , steps : AnimationMetadata | AnimationMetadata [], options ?: AnimationOptions ): AnimationTransitionMetadata
Defines styles for an animation state style ( tokens : '*' | { [key: string]: string | number } | Array < '*' | { [key: string]: string | number } > ): AnimationStyleMetadata
Defines timing and styles for animation animate ( timings : string | number , styles ?: AnimationStyleMetadata | AnimationKeyframesSequenceMetadata ): AnimationAnimateMetadata
Composition Functions
Runs animation steps sequentially sequence ( steps : AnimationMetadata [], options ?: AnimationOptions ): AnimationSequenceMetadata
Runs animation steps in parallel group ( steps : AnimationMetadata [], options ?: AnimationOptions ): AnimationGroupMetadata
Defines keyframe-based animation keyframes ( steps : AnimationStyleMetadata []): AnimationKeyframesSequenceMetadata
Queries child elements for animation query ( selector : string , animation : AnimationMetadata | AnimationMetadata [], options ?: AnimationQueryOptions ): AnimationQueryMetadata
Staggers animations across multiple elements stagger ( timings : string | number , animation : AnimationMetadata | AnimationMetadata []): AnimationStaggerMetadata
Triggers child animations animateChild ( options ?: AnimateChildOptions ): AnimationAnimateChildMetadata
Reusable Animations
Defines a reusable animation animation ( steps : AnimationMetadata | AnimationMetadata [], options ?: AnimationOptions ): AnimationReferenceMetadata
Uses a reusable animation useAnimation ( animation : AnimationReferenceMetadata , options ?: AnimationOptions ): AnimationAnimateRefMetadata
Constants
Automatically compute style values style ({ height: AUTO_STYLE })
Examples
Complete Component Example
import { Component } from '@angular/core' ;
import { trigger , state , style , transition , animate , keyframes , query , stagger } from '@angular/animations' ;
@ Component ({
selector: 'app-hero-list' ,
template: `
<div class="container">
<button (click)="toggleList()">Toggle List</button>
<ul [@listAnimation]="items.length">
<li *ngFor="let item of items" [@itemAnimation]>
{{ item.name }}
</li>
</ul>
</div>
` ,
animations: [
trigger ( 'listAnimation' , [
transition ( '* => *' , [
query ( ':enter' , [
style ({ opacity: 0 , transform: 'translateY(-15px)' }),
stagger ( '50ms' , [
animate ( '300ms ease-out' ,
style ({ opacity: 1 , transform: 'translateY(0)' })
)
])
], { optional: true })
])
]),
trigger ( 'itemAnimation' , [
transition ( ':enter' , [
style ({ opacity: 0 , transform: 'scale(0.8)' }),
animate ( '200ms cubic-bezier(0.68, -0.55, 0.265, 1.55)' ,
style ({ opacity: 1 , transform: 'scale(1)' })
)
]),
transition ( ':leave' , [
animate ( '200ms ease-in' ,
style ({ opacity: 0 , transform: 'scale(0.8)' })
)
])
])
]
})
export class HeroListComponent {
items = [
{ name: 'Item 1' },
{ name: 'Item 2' },
{ name: 'Item 3' }
];
toggleList () {
this . items = this . items . length > 0 ? [] : [
{ name: 'Item 1' },
{ name: 'Item 2' },
{ name: 'Item 3' }
];
}
}
Browser Support
Angular animations use the Web Animations API. For older browsers, you may need to include a polyfill.
Polyfill Installation
npm install web-animations-js
import 'web-animations-js' ;
Resources
Animations Guide Complete guide to Angular animations
Web Animations API MDN Web Animations documentation
Animation Examples Interactive examples and demos
Performance Tips Web animation performance guide
Start Simple Begin with basic fade and slide animations, then progressively add complexity as needed. Most UI animations should be subtle and fast (200-400ms).