Skip to main content
Ben Nadel at dev.Objective() 2015 (Bloomington, MN) with: Brien Hodges
Ben Nadel at dev.Objective() 2015 (Bloomington, MN) with: Brien Hodges

Styling The Void State Using Animations In Angular 2 RC 6

By
Published in

As I've starting to dig into the Animations support in Angular 2, one thing that seemed non-obvious to me was whether or not the "void" state could be styled. I have seen and demonstrated that you can certainly provide void-oriented styles when transition to and from the "void" state; but, I wasn't sure if the "void" state itself could be styled as stand-alone state() meta-data. Turns out, it can.

Run this demo in my JavaScript Demos project on GitHub.

To be clear, what I wanted to test here was whether or not this kind of meta-data even made sense in the Animations configuration:

state( "void", style({ ... }) )

Here, I'm telling Angular 2 that when the associated element doesn't exist, it should have the given style. From a state-rendering standpoint, this clearly makes no sense - a non-existing element has no style. But, from a state-transition standpoint, it might be helpful.

To test this, I put together a small demo in which I'm adding and removing a Box to the rendered view. In the animation configuration for the @boxAnimation trigger, I'm providing explicit "void" state and non-void state style:

// Import the core angular services.
import { animate } from "@angular/core";
import { Component } from "@angular/core";
import { state } from "@angular/core";
import { style } from "@angular/core";
import { transition } from "@angular/core";
import { trigger } from "@angular/core";

@Component({
	selector: "my-app",
	animations: [
		trigger(
			"boxAnimation",
			[
				// Even though the "void" state is not rendered, per-say, we can style
				// it. This way, when we transition to and from the "void" state,
				// Angular will know what CSS properties to animate.
				state(
					"void",
					style({
						borderRadius: 50,
						opacity: 0.0,
						transform: "rotate( 900deg )"
					})
				),

				// CAUTION: The non-void state needs to be styled for the Web Animations
				// API ** polyfill **. When running in Chrome, which has native support
				// for the Web Animations API, you do NOT need this state() block. If you
				// attempt to omit this in Firefox, however, you get the following error:
				// --
				// Animation to or from an underlying value is not yet supported.
				// --
				state(
					"*",
					style({
						borderRadius: 4,
						opacity: 1.0,
						transform: "rotate( 0deg )"
					})
				),

				// Now, when we transition to and from the "void" state, we don't have
				// to provide additional styles - we only need to provide the relevant
				// animation duration and timing functions.
				transition(
					"void => * , * => void",
					[
						animate( "1000ms ease-in-out" )
					]
				)
			] // End: boxAnimation.
		)
	],
	template:
	`
		<p>
			<a (click)="removeBox()">Remove Box</a>
		</p>

		<div class="container">
			<template [ngIf]="isShowingBox">

				<div @boxAnimation class="box">
					Box
				</div>

			</template>
		</div>
	`
})
export class AppComponent {

	public isShowingBox: boolean;


	// I initialize the component.
	constructor() {

		this.isShowingBox = true;

	}


	// ---
	// PUBLIC METHODS.
	// ---


	// I remove the box from the view-rendering; then, several seconds later, add it
	// back so that it can be removed again.
	public removeBox() : void {

		this.isShowingBox = false;

		// In a few seconds, reset the view.
		setTimeout(
			() : void => {

				this.isShowingBox = true;

			},
			2000
		);

	}

}

Notice that my transition() meta-data doesn't define any styling. That's because it is using the styles provided by the individual state() configurations. The only configuration that we need to provide in the actual transition is the duration and any other optional timing information. And, when we run this in the browser, we can get the following output:

Styling the void state in the animations meta-data in Angular 2 RC 6.

As you can see, the box element is clearly transitioning to and from the "void" state styling.

As a quick side-note, I should mention that the "*" state only needs to be defined in browsers that don't have native support for the Web Animations API. In Chrome, for example - which does have native support - the browser can determine the underlying values for the animating styles and therefore doesn't need the "*" state. In Firefox, on the other hand - which relies on the polyfill - we need to explicitly provide the browser with the underlying target values of the animating properties.

Long-story-short, you can style the "void" state in Angular 2 animation meta-data. This is a helpful feature because it means that you don't have to redefine the void styles in both the "enter" and the "leave" animations for a given element.

Want to use code from this post? Check out the license.

Reader Comments

I believe in love. I believe in compassion. I believe in human rights. I believe that we can afford to give more of these gifts to the world around us because it costs us nothing to be decent and kind and understanding. And, I want you to know that when you land on this site, you are accepted for who you are, no matter how you identify, what truths you live, or whatever kind of goofy shit makes you feel alive! Rock on with your bad self!
Ben Nadel