Runtime Control Over Angular Animations

Angular v12 introduces an exciting capability—the ability to toggle animations off while the application is running. 🎉

Heads up: This functionality arrived in v12.0.0-next.3.

Previously, the sole method for turning off Angular animations involved supplying NoopAnimationsModule. However, this method had a significant drawback—it erased all animations during the build phase. You effectively had to decide at compile time whether your application would include animations or not. There was no way to defer this decision until later, for instance, during the application's launch sequence.

With v12, that limitation is a thing of the past. You can now feed a configuration directly into BrowserAnimationsModule. Presently, this configuration accepts just a single property—disableAnimations. When set to true, it deactivates all animations. The best part? This decision can be made at runtime, right as your app is booting up!

Why Might You Need This?

If you already have scenarios in mind where disabling animations is useful, that's excellent!

One particularly compelling use case involves enhancing accessibility by honoring user preferences for fewer motion effects.

Modern operating systems and browsers offer a setting that users can enable to signal that they prefer reduced motion. You can tap into this preference by using the prefers-reduced-motion CSS media query.

You might wonder how to bridge the gap between a CSS media query and your TypeScript logic. It's simpler than you think! The matchMedia method allows you to evaluate whether a specific media query string matches the current environment. This method returns a MediaQueryList object, where the matches property will be true if the document aligns with the query, or false otherwise.

Let's walk through a practical example (refer to this StackBlitz for a working demo):

import { NgModule } from "@angular/core";
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
import { AppComponent } from "./app.component";

export function prefersReducedMotion(): boolean {
  const mediaQueryList = window.matchMedia("(prefers-reduced-motion)");

  return mediaQueryList.matches;
}

@NgModule({
  imports: [
    BrowserAnimationsModule.withConfig({
      disableAnimations: prefersReducedMotion()
    })
  ],
  declarations: [AppComponent],
  bootstrap: [AppComponent]
})
export class AppModule {}

Here's a demonstration illustrating this behavior on a Windows system:

Alt Text

For guidance on disabling animations across other platforms, refer to the prefers-reduced-motion documentation on MDN.

Keep in mind that after the app has fully launched, you cannot re-enable or disable animations again.

A big shout-out to Kristiyan Kostadinov for this fantastic work.