diff --git a/src/presentation/assets/styles/base/_index.scss b/src/presentation/assets/styles/base/_index.scss index 45edc2bb..081a99b6 100644 --- a/src/presentation/assets/styles/base/_index.scss +++ b/src/presentation/assets/styles/base/_index.scss @@ -13,11 +13,16 @@ @use "_code-styling" as *; @use "_margin-padding" as *; @use "_link-styling" as *; +@use "_prevent-scrollbar-layout-shift" as *; * { box-sizing: border-box; } +html { + @include prevent-scrollbar-layout-shift; +} + body { background: $color-background; @include base-font-style; diff --git a/src/presentation/assets/styles/base/_prevent-scrollbar-layout-shift.scss b/src/presentation/assets/styles/base/_prevent-scrollbar-layout-shift.scss new file mode 100644 index 00000000..73796c53 --- /dev/null +++ b/src/presentation/assets/styles/base/_prevent-scrollbar-layout-shift.scss @@ -0,0 +1,19 @@ +// This mixin prevents layout shifts caused by the appearance of a vertical scrollbar +// in Chromium-based browsers on Linux and Windows. +// It creates a reserved space for the scrollbar, ensuring content remains stable and does +// not shift horizontally when the scrollbar appears. +@mixin prevent-scrollbar-layout-shift { + scrollbar-gutter: stable; + + @supports not (scrollbar-gutter: stable) { // https://caniuse.com/mdn-css_properties_scrollbar-gutter + // Safari workaround: Shift content to accommodate non-overlay scrollbar. + // An issue: On small screens, the appearance of the scrollbar can shift content, due to limited space for + // both content and scrollbar. + $full-width-including-scrollbar: 100vw; + $full-width-excluding-scrollbar: 100%; + $scrollbar-width: calc($full-width-including-scrollbar - $full-width-excluding-scrollbar); + padding-inline-start: $scrollbar-width; // Allows both right-to-left (RTL) and left-to-right (LTR) text direction support + } + + // More details: https://web.archive.org/web/20240509122237/https://stackoverflow.com/questions/1417934/how-to-prevent-scrollbar-from-repositioning-web-page +} diff --git a/src/presentation/components/DevToolkit/DevToolkit.vue b/src/presentation/components/DevToolkit/DevToolkit.vue index dbdd5510..b130bf8c 100644 --- a/src/presentation/components/DevToolkit/DevToolkit.vue +++ b/src/presentation/components/DevToolkit/DevToolkit.vue @@ -31,6 +31,7 @@ import { defineComponent, ref } from 'vue'; import { injectKey } from '@/presentation/injectionSymbols'; import FlatButton from '@/presentation/components/Shared/FlatButton.vue'; import { dumpNames } from './DumpNames'; +import { useScrollbarGutterWidth } from './UseScrollbarGutterWidth'; export default defineComponent({ components: { @@ -39,6 +40,7 @@ export default defineComponent({ setup() { const { log } = injectKey((keys) => keys.useLogger); const isOpen = ref(true); + const scrollbarGutterWidth = useScrollbarGutterWidth(); const devActions: readonly DevAction[] = [ { @@ -58,6 +60,7 @@ export default defineComponent({ devActions, isOpen, close, + scrollbarGutterWidth, }; }, }); @@ -71,10 +74,14 @@ interface DevAction {