38

I am trying to get my material dialog to have an X button at the top right, but I am having problems with the positioning.

component.ts

this.d.open(loginComponent, {
  width: '300px',
  height: '',
  panelClass: 'dialogC',
});

component.html

<mat-dialog-content>
    <button mat-button class="close-icon" [mat-dialog-close]="true">
        <mat-icon>close</mat-icon>
    </button>
    <h2 mat-dialog-title>Login</h2>

style.scss

.dialogC {
  position: relative !important;
}

.close-icon {
  position: absolute;
  top: 0;
  right: 0;
  transform: translate(50%, -50%);
}

The X is just aligned to the left instead of top right. Suggestions?

Update, this is the problem I get after adding flex:

enter image description here

Jonathan
  • 3,893
  • 5
  • 46
  • 77

11 Answers11

31

The easy way now is:

<div mat-dialog-title class="dialog-title">
  <h2>Title</h2>
  <button mat-icon-button aria-label="close dialog" mat-dialog-close>
    <mat-icon>close</mat-icon>
  </button>
</div>

And the dialog-title css is

.dialog-title {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

That's working on Angular 8.0.0

Degs
  • 321
  • 3
  • 5
28
<button class="close" mat-button (click)="onNoClick()">X</button>
<h1 mat-dialog-title>Login</h1>
<div mat-dialog-content>
...
...
</div>

CSS: (Please give it in global (styles.css) or give ViewEncapsulation.NONE or else these styles wont affect.)

.cdk-overlay-pane.my-dialog {
  position: relative!important;
}
.close.mat-button {
  position: absolute;
  top: 0;
  right: 0;
  padding: 5px;
  line-height: 14px;
  min-width: auto;
}

Note that in the CSS We now have a new class out of thin air .my-dialog

So, please mention that as panelClass in dialogRef like below,

this.dialog.open(DialogComponent, {
      width: '250px',
      panelClass: 'my-dialog',
..
..

This yields me the following result,

enter image description here

Fasid Mpm
  • 557
  • 6
  • 10
19

Using mat-icon-button it is necessary to add only the style below to the button.

.close-button{
  float: right;
  top:-24px;
  right:-24px;
}

Functional example:

stackblitz

Alex Parloti
  • 668
  • 1
  • 9
  • 25
  • How can we add that cancel icon outside the dialog? – prasannakumar chebrolu Jul 28 '20 at 15:06
  • @prasannakumarchebrolu see the `openDialog2` method here [app-component.ts](https://stackblitz.com/edit/mat-dialog-close?file=src%2Fapp%2Fapp-component.ts) and the css rules for the `.icon-outside` class here [dialog-component.css](https://stackblitz.com/edit/mat-dialog-close?file=src%2Fapp%2Fdialog%2Fdialog-component.css) – Alex Parloti Jul 28 '20 at 16:18
  • This answer can be marked as approved as well. Thanks! – anown.dev Nov 03 '21 at 10:44
3

You can have the X at the title and display: flex ? Like this,

<div mat-dialog-title class="flex-container">
  <h1>Login</h1>
   <button mat-button class="close-icon" [mat-dialog-close]="true">
        <mat-icon>close</mat-icon>
    </button>
</div>
<div mat-dialog-content>
...
...
</div>

FlexBox to the rescue,

.flex-container { display: flex;}

SideNote: You can still use fxLayout instead of .flex-container

Fasid Mpm
  • 557
  • 6
  • 10
  • 2
    This will move the button to the right parallel to the title. The button is still the height of the title and the dialog still has huge padding and margins. This does not fix the problem. – Jonathan Sep 29 '19 at 23:17
  • I just added an image so you can see what it does with flex. It will go higher, but just not overlayed on top of dialog. – Jonathan Sep 29 '19 at 23:40
3

In your component HTML file add the following markup at the top of all elements.

<div mat-dialog-title style="float: right; font-weight: 700; cursor: pointer;" (click)="close()">X</div>

In your component TS file add the close function as follows.

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

Don't forget to include the dialogRef inside the constructor as an argument

constructor(public dialogRef: MatDialogRef<YourDialogComponent>) {}
Asra Fud Duha
  • 511
  • 5
  • 9
2

What I prefer is doing something like this -

.html file

<button class="close" mat-button mat-dialog-title (click)="closeDialog()">X</button>

By giving mat-dialog-title to the button I make sure it is in the top layer and then I give custom class to it, something like

.css file

.close.mat-button {
    position: inherit;
    top: 0;
    right: 0;
    padding: 2px;
    line-height: 3px;
    min-width: auto;
  }

The button discussed above and my modal-content is in a parent div, which I display as flex and use as flex-direction: column

.dialog{
    display: flex;
    flex-direction: column;
}

.ts file

  closeDialog() {
    this.dialogRef.close();
  }```
Shubham Arya
  • 585
  • 5
  • 18
2

You can acheive this by applying some css styles to mat-icon, you can achieve this.

Mat-dialog looks as below.

<button mat-icon-button class="close-button" [mat-dialog-close]="true">
  <mat-icon class="close-icon" color="warn">close</mat-icon>
</button>
<h1 mat-dialog-title>Hi {{data.name}}</h1>
<div mat-dialog-content>
  <p>Hello World!</p>
</div>

Add the following css rules

// if you want to change the color of the icon
.material-icons.color_white {color: #ffffff;}
.close-button{
  float: right;
  top:-24px;
  right:-24px;
}

//if you want some css animation
.close-icon {
  transition: 1s ease-in-out;
}

.close-icon:hover {
  transform: rotate(180deg);
}

//To place the x mark outside of the container
::ng-deep .icon-outside .close-button{
  float: right;
  top:-52px;
  right:-52px;
}

::ng-deep .icon-outside .mat-dialog-container {
 overflow: unset
}

Your mat-dialog consuming componnet should look as below

constructor(public dialog: MatDialog) {}

  openDialog(): void {
    const dialogRef = this.dialog.open(DialogComponent, {
      width: '250px',
      panelClass:'icon-outside',
      data: {name: 'your name'}
    });

    dialogRef.afterClosed().subscribe(result => {
      console.log('The dialog was closed');
    });
  }

Adding custom class icon-outside is important.

This will change your code as expected. If you are seeking to change the color of the icon, Add these two classes to mat-icon material-icons & color_white

So your button will look as below:

<button mat-icon-button class="close-button icon-outside" [mat-dialog-close]="true">
  <mat-icon class="close-icon material-icons color_white">close</mat-icon>
</button>
Anand Raja
  • 2,676
  • 1
  • 30
  • 35
2

I just ran into the same problem. I've come up with an easier solution using floats. This also aligns the close X with the title, which I find more visually pleasing.

HTML file:

<div>
  <h1 mat-dialog-title style="float: left">Dialog Title</h1>
  <span style="float: right" [mat-dialog-close]>X</span>
</div>

<div mat-dialog-content style="clear: both">
  ...
</div>

Screenshot

Alexander
  • 121
  • 3
1

On our project I did an implementation using flex and css.

.html file

<div fxLayout="column">
    <div fxLayoutAlign="end">
        <button mat-icon-button color="primary" (click)="close()"><mat-icon>close</mat-icon></button>
    </div>
    <mat-card class="pd-2">
         ...  
    </mat-card>
</div>

.ts file

    openMinimumsModal( ) {
        const dialogRef = this.matDialog.open(OrderMinimumsComponent, {
            width: 'auto',
            panelClass: 'dialog-no-padding',
           data: { ... },
        });
        dialogRef.afterClosed().subscribe(() => {});
    }

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

.css file

    .dialog-no-padding .mat-dialog-container {
        padding: 0;
    }

    .pd-2 {
        padding: 0 20px 20px 20px !important;
    }
0

Possible duplicate: 49420069

Close functionality and button alignment without TypeScript.

HTML:

<button class="button-close" mat-button [mat-dialog-close]="true">X</button>

CSS:

.button-close {
    justify-self: right;
    font-size: 20px;
    border: none;
    height: 30px;
    background-color: #FFFFFF;
    outline: none;
    color: #c04747;
    
    &:hover {
        cursor: pointer;
    }
}
piritocle
  • 318
  • 2
  • 10
0

I have something like this

html:

<div class="header-and-close">
  <h1 mat-dialog-title>Header</h1>
  <button type="button" mat-icon-button (click)="closeDialog()" class="close-button">
    <mat-icon aria-hidden="false" aria-label="Close icon">close</mat-icon>
  </button>
</div>

ts component:

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

  closeDialog() {
    this.dialogRef.close();
  }

css:

.header-and-close {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
}