ng-bootstrap modal animation

18,164

Solution 1

Here is simple solution. Just put it in style.css

/* modal animation */
.modal-content{
  animation-name: example;
  animation-duration: 0.3s;
}

@keyframes example {
  0%   {transform: scale(0.5)}
  75%  {transform: scale(1.1)}
  100% {transform: scale(1)}
}

Solution 2

You need to add animation css class to global styles and add NgbModalOptions.

styles.css: // or whatever is your global css

.modal-holder{
  animation-name: example;
  animation-duration: 0.3s;
}

@keyframes example {
  0%   {transform: scale(0.5)}
  100% {transform: scale(1)}
}

modal.component.ts

const modalRef = this.modalService.open(NgbdModalContent, {windowClass: 'modal-holder', centered: true});

Enough talk, you can see example on:

StackBlitz

Solution 3

Here is the exact replica of FADE IN - OUT animation with SLIDE DOWN as of bootstrap 4.x

SOLUTION 1: Initialize animation in constructor

app.component.ts:-

import { NgbModal, NgbModalRef } from "@ng-bootstrap/ng-bootstrap";
  constructor(private modalService: NgbModal) {
    NgbModalRef.prototype["c"] = NgbModalRef.prototype.close;
    NgbModalRef.prototype.close = function(reason: string) {
      document.querySelector(".modal-backdrop").classList.remove("show");
      document.querySelector(".modal").classList.remove("show");
      setTimeout(() => {
        this["c"](reason);
      }, 500);
    };
    NgbModalRef.prototype["d"] = NgbModalRef.prototype.dismiss;
    NgbModalRef.prototype.dismiss = function(reason: string) {
      document.querySelector(".modal-backdrop").classList.remove("show");
      document.querySelector(".modal").classList.remove("show");
      setTimeout(() => {
        this["d"](reason);
      }, 500);
    };
  }
  open(basic) {
    this.modalService.open(basic);
  }

app.component.html :-

<div class="card">
    <div class="card-header">
        <h4 class="card-title">Basic Modal</h4>
    </div>
    <div class="card-content">
        <div class="card-body">
            <div class="row">
                <div class="col-sm-12">
                    <p>Toggle a modal via TypeScript by clicking the button above.</p>
                    <!-- Button trigger modal -->
                    <button type="button" (click)="open(basic)" class="btn btn-outline-primary block btn-lg">
                  Launch Modal
                </button>

                    <!-- Modal -->
                    <ng-template #basic let-modal>
                        <div class="modal-header">
                            <h4 class="modal-title" id="myModalLabel1">Basic Modal</h4>
                            <button type="button" class="close" (click)="modal.dismiss('Cross click')" aria-label="Close">
                      <span aria-hidden="true">&times;</span>
                    </button>
                        </div>
                        <div class="modal-body" tabindex="0" ngbAutofocus>
                            <h5>Check First Paragraph</h5>
                            <p>Oat cake ice cream candy chocolate cake chocolate cake cotton candy dragée apple pie.
                                Brownie carrot cake candy canes bonbon fruitcake topping halvah. Cake sweet roll cake
                                cheesecake cookie chocolate cake liquorice.</p>
                        </div>
                        <div class="modal-footer">
                            <button type="button" class="btn btn-primary" (click)="modal.close('Accept click')">Accept</button>
                        </div>
                    </ng-template>
                    <!-- / Modal -->

                </div>
            </div>
        </div>
    </div>
</div>

styles.scss :-

// modal animation
@keyframes modal-fade {
  from {
    top: -50px;
    opacity: 0;
  }

  to {
    top: 0;
    opacity: 1;
  }
}

.modal {
  top: -100px;
  animation: ease-in-out .3s modal-fade;

  &.show {
    top: 0;
  }
    .modal-body {
    &:focus {
      outline: none;
    }
  }
}

stackblitz link here

SOLUTION 2: initalize animation in individual modal call

app.component.ts :-

import { NgbModal } from "@ng-bootstrap/ng-bootstrap";
  constructor(private ngbModal: NgbModal) {}

  open(content: any, config?: any) {
    let modal = this.ngbModal.open(content, config);
    let instance = (modal as any)._windowCmptRef.instance;
    setImmediate(() => {
      instance.windowClass = "custom-show";
    });

    let fx = (modal as any)._removeModalElements.bind(modal);
    (modal as any)._removeModalElements = () => {
      instance.windowClass = "";
      setTimeout(fx, 250);
    };

    return modal;
  }

app.component.html :-

<div class="card">
    <div class="card-header">
        <h4 class="card-title">Basic Modal</h4>
    </div>
    <div class="card-content">
        <div class="card-body">
            <div class="row">
                <div class="col-sm-12">
                    <p>Toggle a modal via TypeScript by clicking the button above.</p>
                    <!-- Button trigger modal -->
                    <button type="button" (click)="open(basic)" class="btn btn-outline-primary block btn-lg">
                  Launch Modal
                </button>

                    <!-- Modal -->
                    <ng-template #basic let-modal>
                        <div class="modal-header">
                            <h4 class="modal-title" id="myModalLabel1">Basic Modal</h4>
                            <button type="button" class="close" (click)="modal.dismiss('Cross click')" aria-label="Close">
                      <span aria-hidden="true">&times;</span>
                    </button>
                        </div>
                        <div class="modal-body" tabindex="0" ngbAutofocus>
                            <h5>Check First Paragraph</h5>
                            <p>Oat cake ice cream candy chocolate cake chocolate cake cotton candy dragée apple pie.
                                Brownie carrot cake candy canes bonbon fruitcake topping halvah. Cake sweet roll cake
                                cheesecake cookie chocolate cake liquorice.</p>
                        </div>
                        <div class="modal-footer">
                            <button type="button" class="btn btn-primary" (click)="modal.close('Accept click')">Accept</button>
                        </div>
                    </ng-template>
                    <!-- / Modal -->

                </div>
            </div>
        </div>
    </div>
</div>

styles.scss :-

// animation style 
// --------------------------
.modal {
    &.show .modal-dialog {
        transition: 0.25s all;
        // opacity: 0;
        transform: translate(0, -5vh);
    }

    &.custom-show .modal-dialog {
        opacity: 1;
        transform: translate(0, 0);
    }
  .modal-body {
    &:focus {
      outline: none;
    }
  }
}

stackblitz link here

Share:
18,164
72GM
Author by

72GM

Updated on July 01, 2022

Comments

  • 72GM
    72GM almost 2 years

    The fade class doesn't appear to work on the ngb-modal.

    I've looked at trying to apply my own animation to the modal but the modal template is obviously injected into modal dialogue by ng-bootstrap e.g. I don't have access to the modal dialogue. I only have access to the template:

    <template #content let-c="close" let-d="dismiss">
      <div class="modal-header card-header" style="border-radius: 10px;">
        <h4 class="modal-title">Contact Form</h4>
     </div>
        <div class="modal-body"> </div>
    ...etc
    </template>
    

    I need to apply my animation to the top level dialogue otherwise just bits of the modal animate. If I apply it to the template it blows up.

    Any idea how I would animate the whole modal??

  • Darryl Mendonez
    Darryl Mendonez about 5 years
    This only has animation for the modal entrance and not exit which is not ideal.
  • Saptarshee Das
    Saptarshee Das over 4 years
    @DarrylMendonez Do you have any other way to do it?
  • Leo
    Leo over 3 years
    thank u. this solution helped me to have animation on the close event too; other solutions work only for show =)
  • Parth Developer
    Parth Developer over 3 years
    The good news is ng-bootstrap is planning for animation support !!
  • Tonio
    Tonio over 2 years
    I managed to do it (animation on close) following this simple example: stackoverflow.com/a/43329484/4834117