Staggered Animation in Ionic Angular
Recently, Josh Morony published an interesting tutorial about staggered animations in Ionic. Since he's using StencilJS, there are some syntax changes required to make his sample code work with Angular. It wasn't as trivial as I expected.
His approach is based on CSS variables that are set in individual list items:
<ion-list lines="none">
<ion-item style="--animation-order: 0">
<ion-label>One</ion-label>
</ion-item>
<ion-item style="--animation-order: 1">
<ion-label>Two</ion-label>
</ion-item>
<ion-item style="--animation-order: 2">
<ion-label>Three</ion-label>
</ion-item>
<ion-item style="--animation-order: 3">
<ion-label>Four</ion-label>
</ion-item>
<ion-item style="--animation-order: 4">
<ion-label>Five</ion-label>
</ion-item>
</ion-list>
The value of the variable is then used in CSS to parameterize the animation-delay:
ion-item {
animation: popIn 0.2s calc(var(--animation-order) * 70ms) both ease-in;
}
@keyframes popIn {
0% {
opacity: 0;
transform: scale(0.6) translateY(-8px);
}
100% {
opacity: 1;
transform: none;
}
}
Of course, list items usually aren't hardcoded. Hence, a binding must be used to set the correct value to the CSS variable. Unfortunately, the ngStyle
directive doesn't work with CSS variables:
<ion-list lines="none">
<ion-item *ngFor="let item of items; index as i"
[ngStyle]="{'--animation-order': i}">
<ion-label>{{item}}</ion-label>
</ion-item>
</ion-list>
Neither does style binding:
<ion-list lines="none">
<ion-item *ngFor="let item of items; index as i"
[style.--animation-order]="i">
<ion-label>{{item}}</ion-label>
</ion-item>
</ion-list>
I found a workaround for that in a related GitHub issue:
<ion-list lines="none">
<ion-item *ngFor="let item of items; index as i"
[attr.style]="sanitizer.bypassSecurityTrustStyle('--animation-order: ' + i)">
<ion-label>{{item}}</ion-label>
</ion-item>
</ion-list>
DomSanitizer
must be injected into the page for this to work:
constructor(public sanitizer: DomSanitizer) {}
If you're using Ionic 5, you can update your project to Angular 9. This will allow you to use style binding syntax:
<ion-list lines="none">
<ion-item *ngFor="let item of items; index as i"
[style.--animation-order]="i">
<ion-label>{{item}}</ion-label>
</ion-item>
</ion-list>
However, even in Angular 9, the ngStyle
directive still doesn't support CSS variables.
The full source code for the sample project is available in a Bitbucket repository.
This blog post is a part of a series of posts about animations in Ionic.