Angular 2 ngIf and CSS Transition / Animation

I want the div to shift to the right in angular 2 using css.

<div class="note" [ngClass]="{'transition':show}" *ngIf="show"> <p> Notes</p> </div> <button class="btn btn-default" (click)="toggle(show)">Toggle</button> 

I work fine if I use [ngClass] to switch the class and use opacity. But I don’t want this element to be displayed from the very beginning, so first I’ll hide it with ngIf, but then the transition will not work.

 .transition{ -webkit-transition: opacity 1000ms ease-in-out,margin-left 500ms ease-in-out; -moz-transition: opacity 1000ms ease-in-out,margin-left 500ms ease-in-out; -ms-transition: opacity 1000ms ease-in-out,margin-left 500ms ease-in-out ; -o-transition: opacity 1000ms ease-in-out,margin-left 500ms ease-in-out; transition: opacity 1000ms ease-in-out,margin-left 500ms ease-in-out; margin-left: 1500px; width: 200px; opacity: 0; } .transition{ opacity: 100; margin-left: 0; } 
+105
css angular angular-animations
Apr 05 '16 at 5:36
source share
6 answers

update 4.1.0

Plunker

See also https://github.com/angular/angular/blob/master/CHANGELOG.md#400-rc1-2017-02-24

update 2.1.0

Plunker

See Animations at angular.io for more information.

 import { trigger, style, animate, transition } from '@angular/animations'; @Component({ selector: 'my-app', animations: [ trigger( 'enterAnimation', [ transition(':enter', [ style({transform: 'translateX(100%)', opacity: 0}), animate('500ms', style({transform: 'translateX(0)', opacity: 1})) ]), transition(':leave', [ style({transform: 'translateX(0)', opacity: 1}), animate('500ms', style({transform: 'translateX(100%)', opacity: 0})) ]) ] ) ], template: ' <button (click)="show = !show">toggle show ({{show}})</button> <div *ngIf="show" [@enterAnimation]>xxx</div> ' }) export class App { show:boolean = false; } 

original

*ngIf removes an element from the DOM when the expression becomes false . You cannot have a transition to a nonexistent element.

Use hidden instead:

 <div class="note" [ngClass]="{'transition':show}" [hidden]="!show"> 
+178
Apr 05 '16 at 5:38 on
source share

According to the latest angular 2 documentation, you can animate the input and output elements (as in angular 1).

An example of a simple fade animation:

In the corresponding @Component add:

 animations: [ trigger('fadeInOut', [ transition(':enter', [ // :enter is alias to 'void => *' style({opacity:0}), animate(500, style({opacity:1})) ]), transition(':leave', [ // :leave is alias to '* => void' animate(500, style({opacity:0})) ]) ]) ] 

Do not forget to add import

 import {style, state, animate, transition, trigger} from '@angular/animations'; 

The corresponding HTML element of the component should look like this:

 <div *ngIf="toggle" [@fadeInOut]>element</div> 

I created an example slide animation here .

Explanation on "void" and "*":

  • void is the state when ngIf set to false (it applies when the element is not attached to the view).
  • * - There can be many animation states (more in the documentation). The * state takes precedence over all of them as a "wildcard" (in my example, this is the state when ngIf set to true ).

Note (taken from angular docs):

Additional declaration inside the application module, import { BrowserAnimationsModule } from '@angular/platform-browser/animations';

Angular animations are built on top of the standard web animation APIs and run natively in browsers that support it. For other browsers, polyfill is required. Take web-animations.min.js from GitHub and add this to your page.

+118
Sep 06 '16 at 19:04
source share
  trigger('slideIn', [ state('*', style({ 'overflow-y': 'hidden' })), state('void', style({ 'overflow-y': 'hidden' })), transition('* => void', [ style({ height: '*' }), animate(250, style({ height: 0 })) ]), transition('void => *', [ style({ height: '0' }), animate(250, style({ height: '*' })) ]) ]) 
+14
Feb 06 '17 at 14:54
source share

CSS only solution for modern browsers

 @keyframes slidein { 0% {margin-left:1500px;} 100% {margin-left:0px;} } .note { animation-name: slidein; animation-duration: .9s; display: block; } 
+9
Mar 07 '17 at 8:49
source share

I use angular 5 and for ngif to work for me, which is in ngfor, I had to use animateChild, and in the user-detail component I used * ngIf = "user.expanded" to show the hidden user and it worked to go on vacation

  <div *ngFor="let user of users" @flyInParent> <ly-user-detail [user]= "user" @flyIn></user-detail> </div> //the animation file export const FLIP_TRANSITION = [ trigger('flyInParent', [ transition(':enter, :leave', [ query('@*', animateChild()) ]) ]), trigger('flyIn', [ state('void', style({width: '100%', height: '100%'})), state('*', style({width: '100%', height: '100%'})), transition(':enter', [ style({ transform: 'translateY(100%)', position: 'fixed' }), animate('0.5s cubic-bezier(0.35, 0, 0.25, 1)', style({transform: 'translateY(0%)'})) ]), transition(':leave', [ style({ transform: 'translateY(0%)', position: 'fixed' }), animate('0.5s cubic-bezier(0.35, 0, 0.25, 1)', style({transform: 'translateY(100%)'})) ]) ]) ]; 
+3
Dec 03 '17 at 18:37
source share

One way is to use the installer for the ngIf property and set the state as part of updating the value.

Stackblitz example

fade.component.ts

  import { animate, AnimationEvent, state, style, transition, trigger } from '@angular/animations'; import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; export type FadeState = 'visible' | 'hidden'; @Component({ selector: 'app-fade', templateUrl: './fade.component.html', styleUrls: ['./fade.component.scss'], animations: [ trigger('state', [ state( 'visible', style({ opacity: '1' }) ), state( 'hidden', style({ opacity: '0' }) ), transition('* => visible', [animate('500ms ease-out')]), transition('visible => hidden', [animate('500ms ease-out')]) ]) ], changeDetection: ChangeDetectionStrategy.OnPush }) export class FadeComponent { state: FadeState; // tslint:disable-next-line: variable-name private _show: boolean; get show() { return this._show; } @Input() set show(value: boolean) { if (value) { this._show = value; this.state = 'visible'; } else { this.state = 'hidden'; } } animationDone(event: AnimationEvent) { if (event.fromState === 'visible' && event.toState === 'hidden') { this._show = false; } } } 

fade.component.html

  <div *ngIf="show" class="fade" [@state]="state" (@state.done)="animationDone($event)" > <button mat-raised-button color="primary">test</button> </div> 

example.component.css

 :host { display: block; } .fade { opacity: 0; } 
+3
Jan 25 '18 at 3:52
source share



All Articles