ng-bootstrap collapse: How to apply animations?

20,290

Solution 1

Here's a good way to do it, I think, and it works both for revealing and collapsing: (though it doesn't really need ng-bootstrap anymore)

template.html:

<button (click)="isCollapsed = !isCollapsed">Toggle</button>
<p [@smoothCollapse]="isCollapsed?'initial':'final'">
    your data here
</p>

.

component.ts:

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

@Component({
  selector: 'app-my-component',
  templateUrl: './template.html',
  styleUrls: ['./style.scss'],
  animations: [
    trigger('smoothCollapse', [
      state('initial', style({
        height:'0',
        overflow:'hidden',
        opacity:'0'
      })),
      state('final', style({
        overflow:'hidden',
        opacity:'1'
      })),
      transition('initial=>final', animate('750ms')),
      transition('final=>initial', animate('750ms'))
    ]),
  ]
})
export class MyComponent ...

Details:

  • initial height:0 allows to start from nothing
  • not specifying a final height let the element stop growing when it's all displayed
  • overflow:hidden everywhere so your element doesn't run on other elements
  • opacity from 0 to 1 makes it nicer (in my opinion)
  • An important thing which took me some time to realize is to NOT put [ngbCollapse]="isCollapsed" in the <p> otherwise it breaks all the animation. And we don't need it since we set the height to 0

Hope it helps, I spent a day on it :P

Solution 2

Because they use "display: none" to hide and "display: block" to show element, you can't apply "transition" CSS property.

So, force display block, manage height & opacity to toggle hide/show :

.collapse, .collapse.in {
  display: block !important;
  transition: all .25s ease-in-out;
}

.collapse {
 opacity: 0;
 height: 0;
}

.collapse.in {
  opacity: 1;
  height: 100%;
}

With basic transition and opacity/height, it seem to be more smooth.

You can make your own animation with keyframe and apply to .collapse.in to get better toggle hide/show experience.

And then, if you use Angular 2 in your project, you can switch to ng2-bootstrap : http://valor-software.com/ng2-bootstrap/

Solution 3

inside your component you can add something like this:

 animations: [
    trigger('expandCollapse', [
                state('open', style({height: '100%', opacity: 1})),
                state('closed', style({height: 0, opacity: 0})),
                transition('* => *', [animate('100ms')])
            ]),
 ]


 <div [ngbCollapse]="isCollapsed" [@expandCollapse]="isCollapsed ? 'closed' : 'open'"> ... </div>

See more details here https://angular.io/guide/animations#animating-a-simple-transition

Share:
20,290
Boland
Author by

Boland

Updated on July 18, 2020

Comments

  • Boland
    Boland almost 4 years

    I'm using Collapse: https://ng-bootstrap.github.io/#/components/collapse

    However, it does not animate; even not on the demo site. How should I implement this??

  • Boland
    Boland over 7 years
    I've used ng2-bootstrap and had some issues at that time, that's why I switched to ng-bootstrap. Thanks anyway.
  • DaVince
    DaVince over 5 years
    This sort of works, but it animates my element growing in size only once. After that, the unfolding happens instantly and only the opacity effect seems to work. Any clue why?
  • Loveen Dyall
    Loveen Dyall over 5 years
    try changing transition('* => ', [animate('100ms')]) to transition(' <=> *', [animate('100ms')])
  • Alexander Kozachenko
    Alexander Kozachenko about 5 years
    I killed about 4 hours to make simple dropdown animation, and this is closest I could get. thanks a lot.
  • Nikhil K S
    Nikhil K S about 4 years
    it has issue for link on the accordian description with tab click
  • Arun Kumar
    Arun Kumar over 3 years
    It worked but partially. Animation from initial state to final state is visible but from final state to initial state no animation happens.