I\'m using angular 5 and angular material (latest version) and I\'m trying to open a dialog from a page. When I click the button that triggers the opening, the entire website is
For removing the blank white page background, you can use any one of the css :
.cdk-global-scrollblock{
height: auto
}
or
.cdk-global-scrollblock{
position: static !important;
width: initial !important;
overflow-y: inherit !important;
}
In order to fully understand why .cdk-global-scrollblock
is added to the html tag, I want to make a short description of MatDialog Scroll Strategies:
MatDialog
component has the option scrollStrategy
(type ScrollStrategy
), which determines the scroll strategy to be used for the dialog, as described in: https://material.angular.io/components/dialog/api#MatDialogConfig
To associate the scroll strategy, you have to pass in a function, that returns a scroll strategy, to the MatDialogConfig
:
const dialogRef = this.dialog.open(DialogComponent, {
scrollStrategy: this.overlay.scrollStrategies.block()
// .. other options
});
By default, the MatDialog
will use the block
strategy, as found in the source code.
The other available strategies are noop
, reposition
, and close
- as described here.
.cdk-global-scrollblock
css classThis class is added to the html
tag when the block
strategy is used.
It is used to block the scroll of the content behind the dialog, especially on mobile devices (iOS) - that's why position: fixed;
is used. But when this rule is applied, the window will scroll back to the top of the screen. So there is a need to calculate the current the scroll of the window and apply it to the html
tag.
Source code can be found here, in BlockScrollStrategy
class. I will copy some code here:
this._previousScrollPosition = this._viewportRuler.getViewportScrollPosition();
// Note: we're using the `html` node, instead of the `body`, because the `body` may
// have the user agent margin, whereas the `html` is guaranteed not to have one.
root.style.left = coerceCssPixelValue(-this._previousScrollPosition.left);
root.style.top = coerceCssPixelValue(-this._previousScrollPosition.top);
root.classList.add('cdk-global-scrollblock');
1. The real problem is with your css.
For sure that the values for this._previousScrollPosition
are not correct, so double check the css rules added to the html
and body
tags.
I was able to replicate your issue by using the following css:
html, body {
min-height: 100%;
height: 100%;
}
body {
overflow: auto;
}
Example here: https://stackblitz.com/edit/angular-xvucu4.
This can be fixed by removing body { overflow: auto; }
.
Example here: https://stackblitz.com/edit/angular-xvucu4-jek3zb.
If you really need html
and body
to take 100% of the viewport, even is the content is smaller, use the following css:
html {
height: 100%;
}
body {
min-height: 100%:
}
OR
2. Set noop
scroll strategy:
import {Overlay} from '@angular/cdk/overlay';
constructor {
public overlay: Overlay
}
const dialogRef = this.dialog.open(DialogComponent, {
scrollStrategy: this.overlay.scrollStrategies.noop()
// .. other options
});
The page content will scroll, even if the dialog is opened.
Example: https://stackblitz.com/edit/angular-xvucu4-t4uwwb.