> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/angular/angular/llms.txt
> Use this file to discover all available pages before exploring further.

# @angular/animations

> Angular Animations API - Create fluid, performant animations for Angular applications

# @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.

<Info>
  **Web Standards Based**

  Angular animations are built on the Web Animations API, providing high-performance animations that run efficiently in modern browsers.
</Info>

## Installation

```bash theme={null}
npm install @angular/animations
```

## Quick Start

### 1. Import the Module

Add `BrowserAnimationsModule` to your application:

```typescript app.config.ts theme={null}
import { provideAnimations } from '@angular/animations/browser';

export const appConfig: ApplicationConfig = {
  providers: [
    provideAnimations(),
    // ... other providers
  ]
};
```

### 2. Define an Animation

Create animation triggers in your component:

```typescript example.component.ts theme={null}
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:

```html theme={null}
<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:

<ParamField path="trigger()" type="function">
  Creates a named animation trigger

  ```typescript theme={null}
  trigger('myAnimation', [
    // animation steps
  ])
  ```

  <Expandable title="parameters">
    <ParamField path="name" type="string" required>
      Unique name for the animation trigger
    </ParamField>

    <ParamField path="definitions" type="AnimationMetadata[]" required>
      Array of animation states and transitions
    </ParamField>
  </Expandable>
</ParamField>

### States

Define the appearance of an element in different states:

```typescript theme={null}
state('inactive', style({
  backgroundColor: '#eee',
  transform: 'scale(1)'
}))

state('active', style({
  backgroundColor: '#007bff',
  transform: 'scale(1.1)'
}))
```

<Tip>
  Use the wildcard state `*` to match any state, or `void` to represent an element entering or leaving the DOM.
</Tip>

### Transitions

Define how elements animate between states:

```typescript theme={null}
// 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:

```typescript theme={null}
style({
  opacity: 0,
  transform: 'translateX(-100%)',
  backgroundColor: '#f0f0f0'
})
```

<Note>
  Use `'*'` or the special `AUTO_STYLE` constant to let Angular compute the value automatically.
</Note>

## Animation Functions

### animate()

Specifies timing and styles for an animation step:

<CodeGroup>
  ```typescript Simple Duration theme={null}
  animate('500ms')
  ```

  ```typescript With Easing theme={null}
  animate('500ms ease-in-out')
  ```

  ```typescript With Delay theme={null}
  animate('500ms 100ms ease-in')
  ```

  ```typescript With Styles theme={null}
  animate('500ms', style({ opacity: 0 }))
  ```
</CodeGroup>

**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:

```typescript theme={null}
sequence([
  animate('200ms', style({ opacity: 0.5 })),
  animate('300ms', style({ transform: 'translateY(100px)' })),
  animate('200ms', style({ opacity: 1 }))
])
```

### group()

Runs animation steps in parallel:

```typescript theme={null}
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:

```typescript theme={null}
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 })
]))
```

<Tip>
  The `offset` property (0 to 1) specifies when each keyframe occurs during the animation.
</Tip>

### query()

Query child elements to animate them:

```typescript theme={null}
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:

```typescript theme={null}
query('.list-item', [
  stagger('100ms', [
    animate('300ms ease-out', style({ opacity: 1, transform: 'translateY(0)' }))
  ])
])
```

### animateChild()

Trigger child animations explicitly:

```typescript theme={null}
transition('* => *', [
  query('@childAnimation', [
    animateChild()
  ])
])
```

## Common Animation Patterns

### Fade In/Out

<CodeGroup>
  ```typescript Enter theme={null}
  transition(':enter', [
    style({ opacity: 0 }),
    animate('300ms', style({ opacity: 1 }))
  ])
  ```

  ```typescript Leave theme={null}
  transition(':leave', [
    animate('300ms', style({ opacity: 0 }))
  ])
  ```

  ```typescript Both theme={null}
  trigger('fade', [
    transition(':enter', [
      style({ opacity: 0 }),
      animate('300ms ease-in', style({ opacity: 1 }))
    ]),
    transition(':leave', [
      animate('300ms ease-out', style({ opacity: 0 }))
    ])
  ])
  ```
</CodeGroup>

### Slide In/Out

```typescript theme={null}
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

```typescript theme={null}
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

```typescript theme={null}
trigger('rotate', [
  state('default', style({ transform: 'rotate(0)' })),
  state('rotated', style({ transform: 'rotate(360deg)' })),
  transition('default <=> rotated', animate('500ms ease-in-out'))
])
```

### List Animations

```typescript theme={null}
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:

```typescript animations.ts theme={null}
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:

```typescript theme={null}
@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);
  }
}
```

<ParamField path="AnimationEvent" type="interface">
  Animation lifecycle event

  <Expandable title="properties">
    <ParamField path="fromState" type="string">
      The state the element is transitioning from
    </ParamField>

    <ParamField path="toState" type="string">
      The state the element is transitioning to
    </ParamField>

    <ParamField path="totalTime" type="number">
      Total animation time in milliseconds
    </ParamField>

    <ParamField path="phaseName" type="'start' | 'done'">
      Animation lifecycle phase
    </ParamField>

    <ParamField path="element" type="any">
      The animated element
    </ParamField>

    <ParamField path="triggerName" type="string">
      Name of the animation trigger
    </ParamField>
  </Expandable>
</ParamField>

### Animation Parameters

Pass parameters to animations:

```typescript theme={null}
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:

```typescript theme={null}
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();
}
```

<ParamField path="AnimationBuilder" type="service">
  Programmatic animation builder

  <Expandable title="methods">
    <ParamField path="build()" type="method">
      Creates an animation factory from metadata

      ```typescript theme={null}
      build(animation: AnimationMetadata | AnimationMetadata[]): AnimationFactory
      ```
    </ParamField>
  </Expandable>
</ParamField>

<ParamField path="AnimationPlayer" type="interface">
  Controls animation playback

  <Expandable title="methods">
    <ParamField path="play()" type="method">
      Start the animation
    </ParamField>

    <ParamField path="pause()" type="method">
      Pause the animation
    </ParamField>

    <ParamField path="finish()" type="method">
      Jump to the end state
    </ParamField>

    <ParamField path="reset()" type="method">
      Reset to the beginning
    </ParamField>

    <ParamField path="destroy()" type="method">
      Clean up the animation
    </ParamField>
  </Expandable>
</ParamField>

## Route Animations

Animate navigation between routes:

```typescript route-animations.ts theme={null}
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 })
  ])
]);
```

```typescript app.component.ts theme={null}
@Component({
  template: `
    <div [@routeAnimations]="getRouteAnimationData()">
      <router-outlet />
    </div>
  `,
  animations: [routeAnimations]
})
export class AppComponent {
  getRouteAnimationData() {
    // Return route data for animation state
  }
}
```

## Performance Optimization

<CardGroup cols={2}>
  <Card title="Use transform & opacity" icon="rocket">
    Animate `transform` and `opacity` for GPU acceleration. Avoid animating `width`, `height`, `top`, or `left`.
  </Card>

  <Card title="Disable animations" icon="toggle-off">
    Use `NoopAnimationsModule` in tests or for users who prefer reduced motion
  </Card>

  <Card title="Query options" icon="filter">
    Use `{ optional: true }` in queries to prevent errors when elements don't exist
  </Card>

  <Card title="Clean up" icon="broom">
    Animations clean up automatically, but call `destroy()` on manual players
  </Card>
</CardGroup>

### Disable Animations

```typescript theme={null}
import { provideNoopAnimations } from '@angular/animations/browser';

export const appConfig: ApplicationConfig = {
  providers: [
    provideNoopAnimations(), // Disables all animations
  ]
};
```

### Respect User Preferences

```typescript theme={null}
@media (prefers-reduced-motion: reduce) {
  * {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}
```

## API Reference

### Core Functions

<AccordionGroup>
  <Accordion title="trigger()">
    Creates a named animation trigger

    ```typescript theme={null}
    trigger(name: string, definitions: AnimationMetadata[]): AnimationTriggerMetadata
    ```
  </Accordion>

  <Accordion title="state()">
    Defines a named state with styles

    ```typescript theme={null}
    state(name: string, styles: AnimationStyleMetadata, options?: AnimationOptions): AnimationStateMetadata
    ```
  </Accordion>

  <Accordion title="transition()">
    Defines a transition between states

    ```typescript theme={null}
    transition(stateChangeExpr: string, steps: AnimationMetadata | AnimationMetadata[], options?: AnimationOptions): AnimationTransitionMetadata
    ```
  </Accordion>

  <Accordion title="style()">
    Defines styles for an animation state

    ```typescript theme={null}
    style(tokens: '*' | { [key: string]: string | number } | Array<'*' | { [key: string]: string | number }>): AnimationStyleMetadata
    ```
  </Accordion>

  <Accordion title="animate()">
    Defines timing and styles for animation

    ```typescript theme={null}
    animate(timings: string | number, styles?: AnimationStyleMetadata | AnimationKeyframesSequenceMetadata): AnimationAnimateMetadata
    ```
  </Accordion>
</AccordionGroup>

### Composition Functions

<AccordionGroup>
  <Accordion title="sequence()">
    Runs animation steps sequentially

    ```typescript theme={null}
    sequence(steps: AnimationMetadata[], options?: AnimationOptions): AnimationSequenceMetadata
    ```
  </Accordion>

  <Accordion title="group()">
    Runs animation steps in parallel

    ```typescript theme={null}
    group(steps: AnimationMetadata[], options?: AnimationOptions): AnimationGroupMetadata
    ```
  </Accordion>

  <Accordion title="keyframes()">
    Defines keyframe-based animation

    ```typescript theme={null}
    keyframes(steps: AnimationStyleMetadata[]): AnimationKeyframesSequenceMetadata
    ```
  </Accordion>

  <Accordion title="query()">
    Queries child elements for animation

    ```typescript theme={null}
    query(selector: string, animation: AnimationMetadata | AnimationMetadata[], options?: AnimationQueryOptions): AnimationQueryMetadata
    ```
  </Accordion>

  <Accordion title="stagger()">
    Staggers animations across multiple elements

    ```typescript theme={null}
    stagger(timings: string | number, animation: AnimationMetadata | AnimationMetadata[]): AnimationStaggerMetadata
    ```
  </Accordion>

  <Accordion title="animateChild()">
    Triggers child animations

    ```typescript theme={null}
    animateChild(options?: AnimateChildOptions): AnimationAnimateChildMetadata
    ```
  </Accordion>
</AccordionGroup>

### Reusable Animations

<AccordionGroup>
  <Accordion title="animation()">
    Defines a reusable animation

    ```typescript theme={null}
    animation(steps: AnimationMetadata | AnimationMetadata[], options?: AnimationOptions): AnimationReferenceMetadata
    ```
  </Accordion>

  <Accordion title="useAnimation()">
    Uses a reusable animation

    ```typescript theme={null}
    useAnimation(animation: AnimationReferenceMetadata, options?: AnimationOptions): AnimationAnimateRefMetadata
    ```
  </Accordion>
</AccordionGroup>

### Constants

<ParamField path="AUTO_STYLE" type="const">
  Automatically compute style values

  ```typescript theme={null}
  style({ height: AUTO_STYLE })
  ```
</ParamField>

## Examples

### Complete Component Example

```typescript theme={null}
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

<Note>
  Angular animations use the Web Animations API. For older browsers, you may need to include a polyfill.
</Note>

### Polyfill Installation

```bash theme={null}
npm install web-animations-js
```

```typescript polyfills.ts theme={null}
import 'web-animations-js';
```

## Resources

<CardGroup cols={2}>
  <Card title="Animations Guide" icon="book" href="https://angular.dev/guide/animations">
    Complete guide to Angular animations
  </Card>

  <Card title="Web Animations API" icon="globe" href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Animations_API">
    MDN Web Animations documentation
  </Card>

  <Card title="Animation Examples" icon="code" href="https://angular.io/guide/animations">
    Interactive examples and demos
  </Card>

  <Card title="Performance Tips" icon="gauge-high" href="https://web.dev/animations-guide/">
    Web animation performance guide
  </Card>
</CardGroup>

***

<Tip>
  **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).
</Tip>
