diff --git a/site/src/index.css b/site/src/index.css index d72ebcdf6c873..8cea83ae2b605 100644 --- a/site/src/index.css +++ b/site/src/index.css @@ -744,15 +744,22 @@ scrollbar-color: hsl(var(--surface-quaternary)) transparent; } - /* Prevent layout shift when modals open by maintaining scrollbar width. - scrollbar-gutter: stable reserves space for the scrollbar so Radix's - scroll-bar compensation (margin-right/padding-right) is unnecessary - and causes double spacing. We zero it out with !important to win - over Radix's injected !important styles. The @supports guard ensures - we only do this on browsers that actually support scrollbar-gutter. - - There’s a related issue on GitHub: Radix UI Primitives Issue #3251 - https://github.com/radix-ui/primitives/issues/3251 + /* Prevent layout shift when modals and dropdowns open. + + scrollbar-gutter: stable reserves space for the scrollbar. When Radix + locks the scroll, Radix hides the body scrollbar and injects + margin-right and padding-right. The reserved gutter already keeps the + page width constant. The injected compensation adds a second space and + causes a shift. Set --removed-body-scroll-bar-size and margin-right to + 0 with !important to disable the compensation. The @supports guard + applies these rules only to browsers that support scrollbar-gutter. + + Do not set overflow-y on body[data-scroll-locked]. A forced overflow-y + overrides the scroll lock. On pages that set overflow: hidden on + (for example /agents), the body then shows a new scrollbar and + the page width changes. + + Related issue: https://github.com/radix-ui/primitives/issues/3251 */ @supports (scrollbar-gutter: stable) { html { @@ -762,7 +769,6 @@ html body[data-scroll-locked] { --removed-body-scroll-bar-size: 0 !important; margin-right: 0 !important; - overflow-y: scroll !important; } } diff --git a/site/src/pages/AgentsPage/AgentsPageLayout.tsx b/site/src/pages/AgentsPage/AgentsPageLayout.tsx index 052ea68310156..bfdc1ca0f0f86 100644 --- a/site/src/pages/AgentsPage/AgentsPageLayout.tsx +++ b/site/src/pages/AgentsPage/AgentsPageLayout.tsx @@ -180,23 +180,13 @@ const AgentsPageLayout: FC = () => { const [isSearchDialogOpen, setIsSearchDialogOpen] = useState(false); // The global CSS sets scrollbar-gutter: stable on to prevent - // layout shift on pages that toggle scrollbars. The agents page - // uses its own internal scroll containers so the reserved gutter - // space is unnecessary and wastes horizontal room. + // layout shift on pages that show and hide a scrollbar. The agents + // page scrolls in internal containers only. The reserved gutter is + // not necessary and uses horizontal space. // - // Removing the gutter requires three things: - // - // 1. overflow:hidden on both and so neither element - // can produce a scrollbar. - // 2. scrollbar-gutter:auto on so the browser stops - // reserving space for a scrollbar that will never appear. - // This is what makes react-remove-scroll-bar measure a gap of - // 0 when a Radix dropdown opens, so it injects no padding or - // margin compensation. - // 3. An injected