Skip to content

Commit f940d34

Browse files
authored
fix(cdk/overlay): block scroll strategy throwing off scroll behavior feature detection (#17223)
To avoid a scrolling animation when we disable scrollig, we remove and re-set the `scroll-behavior` property on the body without feature checking it. The problem is that since we've set the property to *something*, our `scrollBehaviorSupported` feature check will be thrown off because it checks for `'scrollBehavior' in document.documentElement.style`. Fixes #17221.
1 parent 2255b66 commit f940d34

File tree

2 files changed

+17
-13
lines changed

2 files changed

+17
-13
lines changed

src/cdk/overlay/scroll/block-scroll-strategy.ts

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,16 @@
99
import {ScrollStrategy} from './scroll-strategy';
1010
import {ViewportRuler} from '@angular/cdk/scrolling';
1111
import {coerceCssPixelValue} from '@angular/cdk/coercion';
12+
import {supportsScrollBehavior} from '@angular/cdk/platform';
1213

13-
/**
14-
* Extended `CSSStyleDeclaration` that includes `scrollBehavior` which isn't part of the
15-
* built-in TS typings. Once it is, this declaration can be removed safely.
16-
* @docs-private
17-
*/
18-
type ScrollBehaviorCSSStyleDeclaration = CSSStyleDeclaration & {scrollBehavior: string};
14+
const scrollBehaviorSupported = supportsScrollBehavior();
1915

2016
/**
2117
* Strategy that will prevent the user from scrolling while the overlay is visible.
2218
*/
2319
export class BlockScrollStrategy implements ScrollStrategy {
2420
private _previousHTMLStyles = {top: '', left: ''};
25-
private _previousScrollPosition: { top: number, left: number };
21+
private _previousScrollPosition: {top: number, left: number};
2622
private _isEnabled = false;
2723
private _document: Document;
2824

@@ -31,7 +27,7 @@ export class BlockScrollStrategy implements ScrollStrategy {
3127
}
3228

3329
/** Attaches this scroll strategy to an overlay. */
34-
attach() { }
30+
attach() {}
3531

3632
/** Blocks page-level scroll while the attached overlay is open. */
3733
enable() {
@@ -58,8 +54,8 @@ export class BlockScrollStrategy implements ScrollStrategy {
5854
if (this._isEnabled) {
5955
const html = this._document.documentElement!;
6056
const body = this._document.body!;
61-
const htmlStyle = html.style as ScrollBehaviorCSSStyleDeclaration;
62-
const bodyStyle = body.style as ScrollBehaviorCSSStyleDeclaration;
57+
const htmlStyle = html.style;
58+
const bodyStyle = body.style;
6359
const previousHtmlScrollBehavior = htmlStyle.scrollBehavior || '';
6460
const previousBodyScrollBehavior = bodyStyle.scrollBehavior || '';
6561

@@ -71,12 +67,19 @@ export class BlockScrollStrategy implements ScrollStrategy {
7167

7268
// Disable user-defined smooth scrolling temporarily while we restore the scroll position.
7369
// See https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-behavior
74-
htmlStyle.scrollBehavior = bodyStyle.scrollBehavior = 'auto';
70+
// Note that we don't mutate the property if the browser doesn't support `scroll-behavior`,
71+
// because it can throw off feature detections in `supportsScrollBehavior` which
72+
// checks for `'scrollBehavior' in documentElement.style`.
73+
if (scrollBehaviorSupported) {
74+
htmlStyle.scrollBehavior = bodyStyle.scrollBehavior = 'auto';
75+
}
7576

7677
window.scroll(this._previousScrollPosition.left, this._previousScrollPosition.top);
7778

78-
htmlStyle.scrollBehavior = previousHtmlScrollBehavior;
79-
bodyStyle.scrollBehavior = previousBodyScrollBehavior;
79+
if (scrollBehaviorSupported) {
80+
htmlStyle.scrollBehavior = previousHtmlScrollBehavior;
81+
bodyStyle.scrollBehavior = previousBodyScrollBehavior;
82+
}
8083
}
8184
}
8285

src/cdk/platform/features/scrolling.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ export function supportsScrollBehavior(): boolean {
3737
// If we're not in the browser, it can't be supported.
3838
if (typeof document !== 'object' || !document) {
3939
scrollBehaviorSupported = false;
40+
return scrollBehaviorSupported;
4041
}
4142

4243
// If the element can have a `scrollBehavior` style, we can be sure that it's supported.

0 commit comments

Comments
 (0)