Let's begin with the dropdown menu, which is the more straightforward of the two examples. For this first demonstration, I'm intentionally keeping things simple by avoiding reusable animations—that concept will come into play with the sidebar example.

To achieve the expand and collapse effect, I'll animate the menu element's height. When the menu opens, it grows from 0px to its full height; when it closes, it shrinks back down to 0px. Each menu item also receives a fade-in effect along with a slight vertical shift. To make the appearance feel more polished, I'll apply a small delay between each item's animation.

Alt Text

The complete code for this animation is available in this Blitz:
https://stackblitz.com/edit/drop-down-menu-animation

Here's the code implementation:

  • The animation relies on two transitions: :enter and :leave. These aliases specifically target the menu element as it enters or leaves the view. For more details on these aliases, refer to the official documentation.
  • Inside the :enter trigger, I first define the menu's starting style as { height: 0, overflow: "hidden" }. After that, I query all menu items and assign each one an initial state of { opacity: 0, transform: "translateY(-50px)" }.
  • The sequence function is then employed to chain two animations so they run one after the other. You can learn more about the sequence function in the Angular animations official documentation.
  • The first animation in the sequence handles the menu expansion using animate("200ms", style({ height: "*" })).
  • The second animation targets each individual menu item. In this step, I use query(".menu-item", [ to select all the items. The stagger function creates a timing offset between each item's animation, and each item then fades in while its Y-axis position is corrected with animate("400ms ease", style({ opacity: 1, transform: "none" })).
  • For the :leave trigger, the process mirrors the :enter trigger, but with the sequence reversed.

This next example introduces a bit more complexity while offering greater flexibility. The key difference here is that I'll build the animation to be reusable. In practice, this means exposing configurable inputs so that consumers of the animation can customize its behavior to suit their needs.

Alt Text

You can see the finished product of this animation in this Blitz:
https://stackblitz.com/edit/side-menu-animation

Here's the code:

  • This implementation closely resembles the previous one. I rely on both :enter and :leave triggers, establish the initial styles for the menu and its items, then animate the menu before querying and animating the items with staggered timing.
  • The animation behavior itself differs, however. In this case, the menu container slides in from the left edge of the viewport, and then each menu item follows suit with a staggered delay.
  • Additionally, this example leverages the animation function, which enables building a reusable animation (further reading on reusable animations is available here). This function also allows defining inputs that can be swapped out at runtime. When creating animations this way, the useAnimation function is required to import the reusable animation into your component.

Resources