diff --git a/docs/pages/resources/changelog.md b/docs/pages/resources/changelog.md index 58fd1ed0..1a507b01 100644 --- a/docs/pages/resources/changelog.md +++ b/docs/pages/resources/changelog.md @@ -14,6 +14,7 @@ New versions of Shoelace are released as-needed and generally occur when a criti ## Next +- Fixed a bug in `` where when it showed it would create a layout shift. [#1967] - Fixed a bug in `` that allowed unwanted text properties to leak in [#1947] ## 2.15.0 diff --git a/src/internal/scroll.ts b/src/internal/scroll.ts index 85939ed5..3cca1b54 100644 --- a/src/internal/scroll.ts +++ b/src/internal/scroll.ts @@ -33,6 +33,19 @@ export function lockBodyScrolling(lockingEl: HTMLElement) { if (!document.documentElement.classList.contains('sl-scroll-lock')) { /** Scrollbar width + body padding calculation can go away once Safari has scrollbar-gutter support. */ const scrollbarWidth = getScrollbarWidth() + getExistingBodyPadding(); // must be measured before the `sl-scroll-lock` class is applied + + let scrollbarGutterProperty = getComputedStyle(document.documentElement).scrollbarGutter; + + // default is auto, unsupported browsers is "undefined" + if (!scrollbarGutterProperty || scrollbarGutterProperty === 'auto') { + scrollbarGutterProperty = 'stable'; + } + + if (scrollbarWidth <= 0) { + // if there's no scrollbar, just set it to "revert" so whatever the user has set gets used. This is useful is the page is not overflowing and showing a scrollbar, or if the user has overflow: hidden, or any other reason a scrollbar may not be showing. + scrollbarGutterProperty = 'revert'; + } + document.documentElement.style.setProperty('--sl-scroll-lock-gutter', scrollbarGutterProperty); document.documentElement.classList.add('sl-scroll-lock'); document.documentElement.style.setProperty('--sl-scroll-lock-size', `${scrollbarWidth}px`); } diff --git a/src/themes/_utility.css b/src/themes/_utility.css index f0e2eefc..6d9fe21e 100644 --- a/src/themes/_utility.css +++ b/src/themes/_utility.css @@ -6,7 +6,10 @@ @supports (scrollbar-gutter: stable) { .sl-scroll-lock { - scrollbar-gutter: stable !important; + scrollbar-gutter: var(--sl-scroll-lock-gutter) !important; + } + + .sl-scroll-lock body { overflow: hidden !important; } }