46

I am trying to customize the default "mat-dialog" in Angular 5. What I want to achieve is having a toolbar in the upper part of the dialog, which should cover the whole width. However, the mat-dialog-container has a fixed padding of 24px which I could not override. I tried to style both the h1 and the mat-dialog-container.

@Component({
selector: 'error-dialog',
template: 
` <h1 mat-dialog-title> ERRORE </h1>             
    <div mat-dialog-content>
        {{data.error}}
    </div>
    <div mat-dialog-actions>
        <button mat-button (click)="onClick()">Ok</button> 
    </div>`,
styles: [
'h1 { background: #E60000; color: white; }',
// 'myDialogStyle .mat-dialog-container { padding: 1px !important;}'
]})

export class ErrorDialog {
constructor(
public dialogRef: MatDialogRef<ErrorDialog>,
@Inject(MAT_DIALOG_DATA) public data: any) { }

onClick(): void {
this.dialogRef.close();
 }
}

openErrorDialog(errore: string): void{
    let dialogRef = this.dialog.open(ErrorDialog, {
        width: '80%',
        data: { error: errore }
        //panelClass: 'myDialogStyle'
    });
}
Ardenne
  • 897
  • 2
  • 13
  • 23

10 Answers10

107

You can pass a custom panelClass in your matDialogConfig Object (doc here)

so

openErrorDialog(errore: string): void{
    let dialogRef = this.dialog.open(ErrorDialog, {
        width: '80%',
        data: { error: errore }
        panelClass: 'custom-modalbox'
    });
}

And in your custom panelClass you can override the padding :

.custom-modalbox {
    mat-dialog-container {
        padding: 0;
    }
}

But your .custom-modalbox should be global scoped to be applied (not defined in the component styles )

onzinsky
  • 541
  • 1
  • 6
  • 21
Pierre Mallet
  • 7,053
  • 2
  • 19
  • 30
  • The property "panelClass" targets the overlay pane and not the dialog itself. The Angular Material Docs suggest to simply provide CSS rules in the global style.css in order to overwrite default material rules/styles. – Francesco Jan 28 '19 at 21:30
  • 1
    @Francesco yes but if you want a specific css for a dialog you need to have a discrimant in your css. So adding a custom panelClass will helps – Pierre Mallet Jan 29 '19 at 08:54
  • 9
    If you use @Component({viewEncapsulation.None}) you can keep the class declaration inside component's CSS file. – NaN Feb 07 '19 at 16:45
  • 5
    @Please_Dont_Bully_Me_SO_Lords I like your approach, but the syntax is like this: `@Component({encapsulation: ViewEncapsulation.None})` – Andy May 08 '19 at 22:39
  • is there a way to set `panelClass` in the HTML no when opening the dialog ? – Mauricio Gracia Gutierrez Feb 10 '22 at 18:33
18

This will definitely work:

::ng-deep.mat-dialog-container {
    padding: 0px !important;
}
Saransh Dhyani
  • 397
  • 3
  • 9
  • 1
    This is the best approach. – Sebastián Rojas Jun 09 '20 at 07:26
  • 2
    I support your answer ng-Deeply ;) – kushal Baldev Jul 10 '20 at 10:12
  • 7
    if you do changes in mat-dialog-container it will be reflected in all the dialog box. Now suppose you have two dialog box one is for error which should come at the bottom (Like snack-bar). and the other is for success which should cover the whole screen. This method won't work there. – samaksh shrivastava Jul 28 '20 at 08:14
  • 4
    ng-deep is deprecated and using !important is a very bad practice... This approach may work, but I wouldn't recommend it. – Arthur Senna Apr 19 '21 at 20:17
  • @ArthurSenna ng-deep is deprecated but no standard alternative has been provided by Angular team - there are techniques that help https://dev.to/jwp/angular-10-ng-deep-and-host-pseudo-classes-1kbg – Mauricio Gracia Gutierrez Feb 10 '22 at 15:20
  • 2
    "This will definitely work" - Not it doesn't. – Eric Mar 02 '22 at 08:20
  • @Eric Please crosscheck your styles it always works am still using it. – Saransh Dhyani Mar 02 '22 at 18:40
  • This should not be used. By using ::ng-deep you break encapsulation of those styles across your application and should be used with caution with Material design since it will cause undesired styles to affect other elements sharing class names. Ways to prevent this: - Use :host as a prefix to your ::ng-deep to keep encapsulation and prevent bleeding of your styles to other elements sharing the same class name. - Style in CSS via adding a class when defining the modal: let dialogRef = this.dialog.open(ErrorDialog, { panelClass: 'my-modal' }); – Ares Jun 06 '22 at 17:04
16

You should use panelClass on the component at the same time as ::ng-deep on the css.

openErrorDialog(errore: string): void{
let dialogRef = this.dialog.open(ErrorDialog, {
    width: '80%',
    data: { error: errore }
    panelClass: 'custom-modalbox'
});
}

in css:

::ng-deep .custom-modalbox {
mat-dialog-container {
    padding: 0;
}
}
Chema
  • 887
  • 8
  • 14
10

I just change this, it works perfectly:

.custom-modalbox >  mat-dialog-container {
        padding: 0px;
}

Here there is a working example: https://stackblitz.com/edit/custom-dialog?file=src/styles.css

Ardenne
  • 897
  • 2
  • 13
  • 23
7

panelClass works perfectly when your styles are global scoped otherwise it won't as styles are not available.

Add ng-deep before your styles to access it globally!!

::ng-deep {

 .custom-dialog > mat-dialog-container {
        padding: 0px;
    }

}
1

The best way to approach the solution is to change the code only at a single place. This can be done be using the code:

::ng-deep.mat-dialog-container {
overflow: visible;
}

This helps you to change the code only at a single place rather than changing at all the places. This works perfectly. No need to declare anything else anywhere apart from the corresponding CSS file.

Kamil Kafoor
  • 256
  • 3
  • 8
1

it worked for me in angular 13

in style.css

::ng-deep #dialogTrasparent{
  padding: 0px !important;
  box-shadow: none !important;
  background: transparent !important;

}

and componenet.ts

const loader = this.dialog.open(DialogLoader, 
{id: 'dialogTrasparent'});
0

Unfortunately, we can't set all desired styles in the mat-dialog config. MatDialogConfig allows you to set only width, height, max/min-width, max/min-height, and custom classes in the config to operate by them for some specific options. But also you can set up global styles for modal in styles.scss file. *.ts

let dialogRef = this.matDialog.open(
   SomeEntryComponent, 
   <MatDialogConfig>modalConfig // <- there you can set width/height
);
    dialogRef.afterClosed().subscribe((result: any) => { /* do stuff */ });

global styles.scss

.cdk-overlay-pane mat-dialog-container.mat-dialog-container { // <- in this way all other styles
  margin: 20px 5px;
  padding: 30px;
}
Igor Kurkov
  • 4,318
  • 2
  • 30
  • 31
0

Define the CSS in the global file and we can use the Mat Dialog API to add the css

Example

   constructor(private dialogRef: MatDialogRef<MetricCreateComponent>) { }

   ngOnInit(): void {
        this.dialogRef.addPanelClass('custom-dialog-container-metric-configure');
    }


    onRemoveClick(): void {
        this.dialogRef.removePanelClass('custom-dialog-container-metric-configure');
    }
San Jaisy
  • 15,327
  • 34
  • 171
  • 290
0

You need to build your own custom class and set it up in the dialog property panelClass.

openDialog(): void {
    const dialogRef = this.dialog.open(DialogOverviewExampleDialog, {
      data: this.data,
      panelClass: 'my-custom-container'
    });
}

In your styles.css/styles.scss you write down your custom rules. Then you said you wanted to style the mat-dialog-title, in order to do that I used the browser inspector and searched for a class name to target (to see the actual class name angular gave it to the html element). I found that name to be 'mat-mdc-dialog-title' and I used it in my rules.

.my-custom-container {
    background-color: aqua;
}
/* Increasing css specificity by duplicating class */
/* Increasing the specificity is important to overwrite angular
   own rules on the component, without it your rules do not win 
   against angular material dialog's rules.
*/
.my-custom-container .mat-mdc-dialog-title.mat-mdc-dialog-title {
    color: blue;
}

Your dialog's html should look something like this:

<section class="my-custom-container">
  <h1 mat-dialog-title>Delete file</h1>
  <div mat-dialog-content>
    Would you like to delete cat.jpeg?
  </div>
  <div mat-dialog-actions>
    <button mat-button mat-button color="accent" mat-dialog-close>No</button>
    <button mat-button mat-raised-button color="primary" mat-dialog-close>Yes</button>
  </div>
</section>
Pepe Alvarez
  • 1,218
  • 1
  • 9
  • 15