Components: Dialogue - overflow scrolling on small screens and margins

Created on 31 Dec 2016  路  20Comments  路  Source: angular/components

Bug, feature request, or proposal:

The current dialogue does not seem to support sizing and scrolling on smaller screen sizes / small devices. This was possible on the material 1 dialogue. If the vertical height of the screen was incredibly small scrollbars would appear see this screenshot:

image

With version 2 - the dialogue is pushed off the screen and no scrollbars ever appear in the middle. It does not maintain any margins on the top or bottom.

image

Maybe there is this a means this can be achieved but the examples are quite primitive.

What is the expected behavior?

When screen is decreased in size scrollbars should appear for the content.

What is the current behavior?

The current dialogue is pushed off the screen with no margin at the top or bottom. The content remains the same size

What are the steps to reproduce?

Providing a Plunker (or similar) is the best way to get the team to see your issue.
https://plnkr.co/edit/DrI42Su0v6OntJkjUNOI?p=preview

What is the use-case or motivation for changing an existing behavior?

The current modal is only useful for very simple use cases.

Which versions of Angular, Material, OS, browsers are affected?

Latest.

Is there anything else we should know?

P3 materiadialog has pr

Most helpful comment

Hi, looks like vh works (>=IE9):

.mat-dialog-container {
  max-height: 70vh !important;
}

All 20 comments

First of all, you're not using the md-dialog-content properly since you're overriding it's height. You're only supposed to wrap your content with it. E.g. <div md-dialog-content style="height: 500px"> should turn into <div md-dialog-content><div style="height: 500px"> in your example.

That being said, I'll take a look at why the element still goes outside of the viewport.

Sorry that was purely for illustration purposes. Thanks for looking into it. I think the main issue here is that because the dialogue is not limited to the screen bounds it never forces "overflow" to work properly on the content area.

If you set up the HTML like I mentioned it will get the overflow, however when you go to a really small screen (< 200px in height), then it starts going out of the viewport. I'm working on a fix for it.

We have been suffering from the same problem.

May I recommend a design suggestion since it is being worked on? It seems like modals are starting to follow a design similar to bootstrap-4's modal or Avenxo's modal. Where the scrolling happens outside the window, rather than within.

Perhaps this window should remain centered until it is near the height of the browser window, then switch to a fixed position 25px from the top, and expands downward.

@crisbeto is this issue still open. I'm also experiencing this problem with 2.0.0-beta.2. I note that this thread was discussed prior to this release.

Please advise.

It is still open. I was working on it a few days ago, but it's a bit tricky to get it working everywhere (IE 11 in particular) with the way we have the overlays set up (we need multiple nested flexboxes which ends up breaking in one way or another). I'm still looking for a proper way to do it.

Is there any update on this? Maybe there's a workaround for the case when dialog is pushed off the screen? I'm trying to make it scrollable but it's not that simple with current layout.

I managed to make dialog scrollable using these styles (from ng-bootstrap):

html {
    position: initial !important;
    overflow-y: initial !important;
}

html.cdk-global-scrollblock body {
    overflow: hidden;
}
.cdk-overlay-container {
    overflow: auto;
}

Although, cdk-global-scrollblock class is added to html only if dialog is opened when there's already a scrollbar shown on the page. If scrollbar is shown after dialog is opened (e.g. dialog is being opened instantly, scrollbars are shown after some ajax requests completed) then cdk-global-scrollblock class won't be added to html

After a lot of juggling with css I stopped on the following styles (works alright in Chrome, FF, IE 11, Edge)

html.cdk-global-scrollblock {
    width: initial;
    position: initial;
    overflow-y: initial;
}

body.modal-open {
    overflow: hidden;
}

body.modal-open .cdk-global-overlay-wrapper {
    pointer-events: all;
    display: block !important;
    overflow: auto;
    padding: 30px 0;
    position: fixed;
}

body.modal-open .cdk-overlay-pane {
    position: relative !important;
    margin: auto !important;
}

.cdk-overlay-backdrop {
    position: fixed !important;
}

.mat-dialog-container {
    margin: 0 auto 30px !important;
    height: auto !important;
    overflow: initial !important;
}

.mat-dialog-content {
    max-width: none !important;
    max-height: none !important;
    overflow: initial !important;
}

Plus .modal-open should be added to body when at least one modal is opened and backdrop div should be moved outside of overlay wrapper and placed before it (like it's done in ng-bootstrap).

Hi, looks like vh works (>=IE9):

.mat-dialog-container {
  max-height: 70vh !important;
}

any fix for this?

+1 The dialog in AngularJs Material is really good, responsive and customisable. The implementation of the dialog in Angular Material is actually a deal breaker. Take a look at the old one, thats how it should work. I want to use Angular Material but i cant work with this..

+1 @crisbeto any update on this? thanks!

@aleixsuau best solution so far! Thank you!

@makkart i am sorry but is that so hard for you ? if it is go to see how ReactJS is doing it.

  constructor(public dialog: MatDialog) {}

  openDialog(): void {
    let dialogRef = this.dialog.open(DialogOverviewExampleDialog, {
      width: '250px',
      data: { name: this.name, animal: this.animal }
    });

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

I prefer do:

.mat-dialog-container .mat-dialog-content { max-height: calc(100vh - 220px) !important; }
In @aleixsuau show 2 scrollbar

I like to build it like the bootstrap modals:

add these styles:

.cdk-global-overlay-wrapper {
  pointer-events: auto !important; // be able to scroll event
  overflow-y: scroll !important;
  align-items: start !important;  // not center the dialog
  z-index: auto !important; // remove z-index
}
.cdk-overlay-pane {
  margin: 1rem;
  z-index: 1002; // over the overlay
}

Note that hacks targeting .cdk-global-overlay-wrapper will probably break the snackbar.

According the docs, dialogs must to follow this basic structure to have a scrollable content:

<h2 mat-dialog-title>Delete all</h2>
<mat-dialog-content>
  <p>THIS IS THE SCROLLABLE CONTENT</p>
</mat-dialog-content>
<mat-dialog-actions>
  <button mat-button mat-dialog-close>No</button>
  <!-- The mat-dialog-close directive optionally accepts a value as a result for the dialog. -->
  <button mat-button [mat-dialog-close]="true">Yes</button>
</mat-dialog-actions>

Add this to your dialog options: autoFocus: false,

e.g:

const dialogRef = this.dialog.open(ProductAlertDialog,{
      width: '100px',
      height: '200px',
      autoFocus: false,
      data: {name: "name", animal: "animal"}
    });

and to css
.mat-dialog-content{
overflow: none;
}

Was this page helpful?
0 / 5 - 0 ratings

Related issues

LoganDupont picture LoganDupont  路  3Comments

jelbourn picture jelbourn  路  3Comments

alanpurple picture alanpurple  路  3Comments

xtianus79 picture xtianus79  路  3Comments

julianobrasil picture julianobrasil  路  3Comments