59

What is the best way to set/override a custom width for a modal?

It seems ng-bootstrap currently supports

size: 'sm' | 'lg'

but Bootstrap 4 supports sm, md and lg.

Ideally I would like the modal to be responsive and adjust similar to container sizes. And on mobile have it go full screen.

EDIT: Bootstrap 4 _variables.scss seems to have a $modal-md setting but appears to be unused.

$modal-lg:                    800px !default;
$modal-md:                    500px !default;
$modal-sm:                    300px !default;
Todd Smith
  • 17,084
  • 11
  • 59
  • 78

13 Answers13

64

The cleanest solution that I could find is to use the windowClass property.

I.e.:

this.modalService.open(MyModalComponent,  { windowClass : "myCustomModalClass"});

Then add the following to your global CSS styles. This is important as the style won't be picked up from your components CSS.

.myCustomModalClass .modal-dialog {
  max-width: 565px;
}
TomDK
  • 1,321
  • 11
  • 16
58

Try like this :

import { NgbModal, NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
import { ModelComponent } from './model.component';

export class Component {

    constructor(private modalService: NgbModal) {}

    open() {
        const modalRef = this.modalService.open(ModelComponent, { size: 'lg', backdrop: 'static' });
    }

}
Bastien
  • 635
  • 5
  • 16
Chandru
  • 10,864
  • 6
  • 38
  • 53
44

I found this as a good solution.

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

ng-deep “shadow-piercing” descendant combinator can be used to force a style down through the child component tree into all the child component views. In this case modal-dialog class.

::ng-deep .my-class .modal-dialog { 
     max-width: 80%;
     width: 80%;
}
ssuperczynski
  • 3,190
  • 3
  • 44
  • 61
DanniFilth
  • 586
  • 4
  • 5
11

When you don't specify the size, the default value use $modal-md (500px).

All the 3 modals sm, md and lg are responsive and will display on full width (with borders) on mobile.

If you really want a new size, you can use a custom size:

this.modalService.open(MyModalComponent, { size: <any>'xl' });

With a css for this class:

.modal-xl {
  max-width: 1000px;
}

EDIT: the xl size is now a standard size so the CSS.

Bastien
  • 635
  • 5
  • 16
  • This fails for me when running npm build. – TomDK Jul 10 '18 at 06:53
  • error on Angular 5 because of unrecognised argument: `Argument of type '{ size: "xl"; }' is not assignable to parameter of type 'NgbModalOptions'. Types of property 'size' are incompatible. Type '"xl"' is not assignable to type '"sm" | "lg"'.` – Alex P. Apr 15 '19 at 16:48
  • I just add the tag which is a workaround until the size type became '"sm" | "lg" | "xl" | string'. – Bastien May 27 '19 at 10:37
  • 4
    Worked for me, don't understand why this is downvoted. – Craig Jul 31 '19 at 21:46
5

add following css in style.css file.

.xlModal > .modal-dialog {
    max-width: 1490px !important;
    min-width: 971px !important;   
    width: 95% !important;
}

Note : we can replace .xlModal with any name.

open modal with new created style.

this.modalService.open(content,{windowClass:"xlModal"});
Kapil Thakkar
  • 840
  • 10
  • 17
2

Add size xl on interface NgbModalOptions.

export interface NgbModalOptions {
   size?: 'sm' | 'lg' | 'xl';
}

Now use it while opening the modal this.modalService.open(content, { size: 'xl' });

Ameerudheen.K
  • 657
  • 1
  • 11
  • 31
2

You could wrap it into a function like

component.ts

// accepts 'sm', 'md' or 'lg' as argument.
// default argument 'md'
public openModal( dialogSize: 'sm' | 'md' | 'lg' = 'md'): void {
  let modalOptions = {};
  if (dialogSize === 'sm' || dialogSize === 'lg') {
    modalOptions = { size: dialogSize };
  } else {
    modalOptions = { windowClass: 'md-class' };
  }
  this.modalService.open(ConfirmationDialogComponent, modalOptions);
}

component.css

::ng-deep .md-class .modal-dialog { 
    max-width: 80%;
    width: 80%;
}

And call it like,

openModal(); //argument 'md'
openModal('sm'); //argument 'sm'
openModal('md'); //argument 'md'
openModal('lg'); //argument 'lg'
naveen
  • 53,448
  • 46
  • 161
  • 251
1

In addition to djpalme and Kapil Thakkar answers, you will need to set the 'encapsulation' of your Component to None as mentioned here

@Component({
    selector: 'app-generic-view',
    templateUrl: './generic-view.component.html',
    styleUrls: ['./generic-view.component.scss'],
    encapsulation: ViewEncapsulation.None
})
YnadW
  • 11
  • 1
1

Add a argument class: 'modal-lg'

open() {
        const modalRef = this.modalService.open(ModelComponent, { class: 'modal-lg', backdrop: 'static' });
    }

}
Khaled Ayed
  • 1,121
  • 3
  • 12
  • 29
0

Try this :

this.modalRef = this.modalService.show(template, { class : "modal-xl"});
PatricioS
  • 111
  • 8
0

Ok I see a lot of partial answers here. I wanted to put what worked for me in the hopes it helps someone else.

I used Kapil Thakkar's answer and YnadW's answer to get it to work. First and foremost, you need to add the Encapsulation part in order for the classes to take hold.

@Component({
   selector: 'app-generic-view',
   templateUrl: './generic-view.component.html',
   styleUrls: ['./generic-view.component.scss'],
   encapsulation: ViewEncapsulation.None
})

Then, I needed to tweak the CSS classes a bit to get the modal properly adjusted. You have to change both the .modal-dialog and .modal-content in order to get the sizing right.

this.modalService.open(modal, { windowClass: 'custom-window-class' });

.custom-window-class > .modal-dialog,
.custom-window-class > .modal-dialog > .modal-content {
   width: 80vw;
   max-width: 80vw;
}
0

This is how you can do it using xl or lg or sm

this.modalService.open(ModalComponent, {
  size: 'xl' or 'lg' or 'sm', scrollable: true, centered: true,
  modalDialogClass: 'dark-modal'
});

You can use either one

openSm(content) {
    this.modalService.open(content, { size: 'sm' });
}

openLg(content) {
    this.modalService.open(content, { size: 'lg' });
}

openXl(content) {
    this.modalService.open(content, { size: 'xl' });
}
R15
  • 13,982
  • 14
  • 97
  • 173
0

In my case, I just wanted to used the 'lg' size for the modal, but it didn't work, even using a custom CSS class didn't work either.

The way I managed to make it work was to add NgbModalConfig in my feature module providers array, and then, where the modal is called (open), I set the size and other values in the component's constructor like the following:

module

import { NgbModalConfig } from '@ng-bootstrap/ng-bootstrap';
@NgModule({
  declarations: [MyComponent, ...],
  imports: [...],
  providers: [NgbModalConfig]
})
export class MyFeatureModule {}

component

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

@Component({...})
export class MyComponent {
  constructor(private config: NgbModalConfig, private modal: NgbModal) {
    this.config.size = 'lg';
  }

  someEvent(): void {
    const modalRef = this.modal.open(MyOtherComponent);
    ...
  }
}
Andres2142
  • 2,622
  • 2
  • 14
  • 19