diff --git a/src/cdk/overlay/scroll/block-scroll-strategy.ts b/src/cdk/overlay/scroll/block-scroll-strategy.ts index 65c625f8b6e9..059f9bf84c02 100644 --- a/src/cdk/overlay/scroll/block-scroll-strategy.ts +++ b/src/cdk/overlay/scroll/block-scroll-strategy.ts @@ -9,20 +9,16 @@ import {ScrollStrategy} from './scroll-strategy'; import {ViewportRuler} from '@angular/cdk/scrolling'; import {coerceCssPixelValue} from '@angular/cdk/coercion'; +import {supportsScrollBehavior} from '@angular/cdk/platform'; -/** - * Extended `CSSStyleDeclaration` that includes `scrollBehavior` which isn't part of the - * built-in TS typings. Once it is, this declaration can be removed safely. - * @docs-private - */ -type ScrollBehaviorCSSStyleDeclaration = CSSStyleDeclaration & {scrollBehavior: string}; +const scrollBehaviorSupported = supportsScrollBehavior(); /** * Strategy that will prevent the user from scrolling while the overlay is visible. */ export class BlockScrollStrategy implements ScrollStrategy { private _previousHTMLStyles = {top: '', left: ''}; - private _previousScrollPosition: { top: number, left: number }; + private _previousScrollPosition: {top: number, left: number}; private _isEnabled = false; private _document: Document; @@ -31,7 +27,7 @@ export class BlockScrollStrategy implements ScrollStrategy { } /** Attaches this scroll strategy to an overlay. */ - attach() { } + attach() {} /** Blocks page-level scroll while the attached overlay is open. */ enable() { @@ -58,8 +54,8 @@ export class BlockScrollStrategy implements ScrollStrategy { if (this._isEnabled) { const html = this._document.documentElement!; const body = this._document.body!; - const htmlStyle = html.style as ScrollBehaviorCSSStyleDeclaration; - const bodyStyle = body.style as ScrollBehaviorCSSStyleDeclaration; + const htmlStyle = html.style; + const bodyStyle = body.style; const previousHtmlScrollBehavior = htmlStyle.scrollBehavior || ''; const previousBodyScrollBehavior = bodyStyle.scrollBehavior || ''; @@ -71,12 +67,19 @@ export class BlockScrollStrategy implements ScrollStrategy { // Disable user-defined smooth scrolling temporarily while we restore the scroll position. // See https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-behavior - htmlStyle.scrollBehavior = bodyStyle.scrollBehavior = 'auto'; + // Note that we don't mutate the property if the browser doesn't support `scroll-behavior`, + // because it can throw off feature detections in `supportsScrollBehavior` which + // checks for `'scrollBehavior' in documentElement.style`. + if (scrollBehaviorSupported) { + htmlStyle.scrollBehavior = bodyStyle.scrollBehavior = 'auto'; + } window.scroll(this._previousScrollPosition.left, this._previousScrollPosition.top); - htmlStyle.scrollBehavior = previousHtmlScrollBehavior; - bodyStyle.scrollBehavior = previousBodyScrollBehavior; + if (scrollBehaviorSupported) { + htmlStyle.scrollBehavior = previousHtmlScrollBehavior; + bodyStyle.scrollBehavior = previousBodyScrollBehavior; + } } } diff --git a/src/cdk/platform/features/scrolling.ts b/src/cdk/platform/features/scrolling.ts index e3e24e2f84d7..5d30bbd2b0bd 100644 --- a/src/cdk/platform/features/scrolling.ts +++ b/src/cdk/platform/features/scrolling.ts @@ -37,6 +37,7 @@ export function supportsScrollBehavior(): boolean { // If we're not in the browser, it can't be supported. if (typeof document !== 'object' || !document) { scrollBehaviorSupported = false; + return scrollBehaviorSupported; } // If the element can have a `scrollBehavior` style, we can be sure that it's supported.