Cory Rylan

My name is , Google Developer Expert, Speaker, Software Developer. Building Design Systems and Web Components.

Follow @coryrylan

Introduction to Angular Router Animations

Cory Rylan

- 3 minutes


This article has been updated to the latest version Angular 15 and tested with Angular 14. The content is likely still applicable for all Angular 2 + versions.

Adding animations can create an excellent user experience when applied appropriately in an application. In this short tutorial, we will show how to use Angular's Animation API to create a simple fade in and fade out effect when we route between components.

Set up Routes

First, we need to set up some routes in our application. In this simple app, we will set a home and about route.

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

import { HomeComponent } from './home/home.component';
import { AboutComponent } from './about/about.component';

export const routes: Routes = [
{ path: '', component: HomeComponent },
{ path: 'about', component: AboutComponent }

imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
export class AppRoutingModule {}

Now that we have our routes set up lets set up our application template.

<a routerLink="">home</a>
<a routerLink="about">about</a>


For now, this will get our routing working but won't have our fade in and fade out animation just yet.

Creating an Animation

First we need to add the Angular Animation module to our application.

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';

import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module';
import { HomeComponent } from './home/home.component';
import { AboutComponent } from './about/about.component';

imports: [BrowserModule, BrowserAnimationsModule, AppRoutingModule],
declarations: [AppComponent, HomeComponent, AboutComponent],
bootstrap: [AppComponent]
export class AppModule {}

We will now add a new file animations.ts. In this file, we will define our fade animation.

import {
} from '@angular/animations';

export const fadeAnimation = trigger('fadeAnimation', [
// The '* => *' will trigger the animation to change between any two states
transition('* => *', [
// The query function has three params.
// First is the event, so this will apply on entering or when the element is added to the DOM.
// Second is a list of styles or animations to apply.
// Third we add a config object with optional set to true, this is to signal
// angular that the animation may not apply as it may or may not be in the DOM.
query(':enter', [style({ opacity: 0 })], { optional: true }),
// here we apply a style and use the animate function to apply the style over 0.3 seconds
[style({ opacity: 1 }), animate('0.3s', style({ opacity: 0 }))],
{ optional: true }
[style({ opacity: 0 }), animate('0.3s', style({ opacity: 1 }))],
{ optional: true }

Now that we have defined our animation we need to explicitly set what element it should be applied to. So let's go back to our application component template.

<a routerLink="">home</a>
<a routerLink="about">about</a>

<main [@fadeAnimation]="o.isActivated ? o.activatedRoute : ''">
<router-outlet #o="outlet"></router-outlet>

On the router outlet, we create a template reference to the outlet directive with the template variable assignment #o="outlet". With this reference to the outlet directive, we can get the information of when the router outlet is active to trigger our fade animation.

Next in our App Component TypeScript file we need to add some information to our component decorator.

import { Component } from '@angular/core';
import { fadeAnimation } from './animations';

selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
animations: [fadeAnimation] // register the animation
export class AppComponent {}

The last missing piece is some CSS in our global style sheet.

router-outlet ~ * {
position: absolute;
height: 100%;
width: 100%;

This selector will select the component that is inserted into the DOM and ensure it fills in the space of its parent element so the animation correctly applies.

To see a full working example check out the demo link below!

View Demo Code   

No spam. Short occasional updates on Web Development articles, videos, and new courses in your inbox.

Related Posts


Using Web Components in Angular Forms with Element Internals

Learn how to create and use Web Components in Angular apps leveraging the new Element Internals APIs.

Read Article
VMWare Clarity

Building forms with Angular and Clarity Design

Learn how to create high-quality forms using Angular and the Clarity Design System.

Read Article

Using HTML5 Date Input with Date Objects and Angular

Learn how to use JavaScript Date Objects with the native HTML5 datepicker and Angular Forms.

Read Article