10

I have an Angular 6 app that I am trying to implement a modal window that slides in from the right side of the screen, like shown here: https://codepen.io/anon/pen/OayRVy

But, no matter what I try, I cannot override the positioning of the modal window. The only thing I have been able to change is things like the background color of the header/body.

My modal HTML:

<ng-template #content let-modal="close">

      <div class="modal-header">
        <h4 class="modal-title" id="modal-basic-title">Table of Contents</h4>
        <button type="button" class="close" data-dismiss="modal" aria-label="Close" (click)="dismissModal(modal)"><span aria-hidden="true">&times;</span></button>
      </div>

      <div class="modal-body">
        <p>
          ....
        </p>
      </div>

</ng-template>

Component code:

  import {NgbModal} from '@ng-bootstrap/ng-bootstrap';

  constructor(private modalService: NgbModal) {}

  public open(content) {
    this.modalService.open(content, {ariaLabelledBy: 'modal-basic-title', size: 'lg'}).result.then((result) => {
      ...
    }, (reason) => {
      ...
    });
  }

If I inspect the HTML and in Chrome DevTools add a float: right property to the .modal-dialog container, it will do what I want. But, adding a

.modal-dialog {
  float: right;
}

to my .scss file for the component has no effect.

Can anyone show me how to override the default bootstrap styling so I can force it to appear on the right side of the screen and take up 100% of the height?

Cody Pritchard
  • 703
  • 2
  • 15
  • 31

4 Answers4

12

Use windowClass from NgbModalOptions

    this.modalService.open(
        content, 
        {
            ariaLabelledBy: 'modal-basic-title', 
            size: 'lg', 
            windowClass: 'custom-class'
        }
    )
    .result
    .then((result) => {
        // write your code here
    });

and in the scss:

.custom-class {
    float: right;
}
20B2
  • 2,011
  • 17
  • 30
Charles Assuncao
  • 548
  • 3
  • 11
12

If you just need to modify an existing class in the modal, like .modal-content, you can just do:

::ng-deep .modal-content  {
  background-color: yellow;
}

If you want to use your own CSS class, here is a more complex example:

::ng-deep .my-class {
  font-size: 2rem;
  .modal-dialog { 
    background-color: yellow;
    padding:1rem;
  }  
  .modal-content {
    color: white;
  }
  .modal-header {
    background-color: red;
  }
  .modal-body {
    background-color: green;
  }
}

and in the *.ts file:

this.modalService.open(content, { windowClass: 'my-class'})

Note that if you are working on a big application, you don't want to use ::ng-deep because it will make the CSS rule global (also, it's deprecated). You can just put .my-class in styles.scss or somewhere where every developer knows that "all rules here are global". That way you can also have a .my-class-2 for a different modal.

mike
  • 1,956
  • 16
  • 22
  • Good one. Simple & effective solution. `::ng-deep .modal-content` did the trick for me. Thanks for giving this solution. – Vibin Guevara Jun 15 '21 at 17:23
8

I had tried using the window.class: 'custom-class' property, but it wasnt working. I would add the custom class declaration and the modal would look exactly the same.

The solution, came from https://ng-bootstrap.github.io/#/components/modal/examples which i had originally modeled my modal after.

They key piece of code here, which they do not explain why its needed or what it does so im still not entirely sure myself, was encapsulation: ViewEncapsulation.None

After adding that line to my @Component declaration, along with the custom class, all the styling worked.

Cody Pritchard
  • 703
  • 2
  • 15
  • 31
  • 3
    `encapsulation: ViewEncapsulation.None` means that you turn off the component encapsulation off, so the component scss populates as part of the global scss which what we may want here and it breaks the angular way. I would want to do is using `ng-deep`, but currently I am still have trouble with it. – roger Jan 29 '19 at 00:20
1

The problem with the solution of add encapsulation: ViewEncapsulation.None it breaks all the style of the component. I found another solution from angular documentation: : https://valor-software.com/ngx-bootstrap/#/modals#service-custom-css-class Through the '''open-modal''' method you add your own class and then you can access the class and model the model. for example:

modalRef: BsModalRef;
  constructor(private modalService: BsModalService) {}

  openModalWithClass(template: TemplateRef<any>) {
    this.modalRef = this.modalService.show(
      template,
      Object.assign({}, { class: 'pupUp-image-modal'})
    );
  }

Css:

.pupUp-image-modal {
    width: fit-content !important;
    max-width: 95% !important;
    max-height: 95%;
}

Note that the model style must be placed in the main style file (style.css) Because the model is not part of the current component