Reserve space for the scrollbar before it even appears
A scrollbar that suddenly appears or disappears shifts the entire visible content by its own width, because under classic overflow: auto it shrinks the available content area. scrollbar-gutter: stable reserves that space permanently, whether the bar is currently visible or not, eliminating one of the most stubborn layout shift bugs on the web.
Table of Contents
- 1. Why an appearing scrollbar triggers a layout shift
- 2. scrollbar-gutter: stable permanently reserves space
- 3. both-edges: reserving symmetric space on both sides
- 4. Differences between operating systems: overlay vs. classic scrollbars
- 5. Combining with overflow: when scrollbar-gutter actually takes effect
- 6. A typical bug: modal opens, background content jumps sideways
- 7. Measuring layout shift: DevTools and the Web Vitals extension
- 8. Browser support and a harmless fallback for older browsers
- 9. Practical use in a shop: category pages, filter lists and checkout
- 10. Summary
- 11. FAQ
1. Why an appearing scrollbar triggers a layout shift
Under the classic overflow: auto rule, the browser only shows a scrollbar once the content actually exceeds the container's height. The problem: once the bar appears, it takes up real space inside the container on many operating systems, shrinking the available content width and causing every element inside to potentially wrap or shift differently. That exact effect shows up frequently when a dropdown menu opens, when content loads via infinite scroll, or when switching between two views with different content lengths.
For users, a jump like that reads as a small stutter that reinforces the impression of an unstable or unfinished page, and for search engines it counts directly toward Cumulative Layout Shift (CLS), one of the three Core Web Vitals. A layout that rewraps every time a scrollbar appears therefore degrades not just the perceived, but also the measurable quality of the page.
2. scrollbar-gutter: stable permanently reserves space
The scrollbar-gutter property solves this by reserving the area a scrollbar would occupy, independent of whether the bar is currently visible. With the value stable, the browser keeps that space free permanently, whether the content is currently overflowing or not, so the scrollbar appearing or disappearing no longer changes the content area's width. The default value is auto, which matches the classic, layout shifting behavior.
The reserved area is called the gutter and behaves like an extra, invisible margin on the relevant edge of the container. Even when no scrollbar is displayed, that margin stays as empty space, which at first glance looks like wasted room but is actually exactly the price a consistently stable layout costs.
/* Permanently reserve space for the scrollbar */
.scroll-container {
overflow-y: auto;
scrollbar-gutter: stable;
max-height: 60vh;
}
3. both-edges: reserving symmetric space on both sides
An additional value, both-edges, combined with stable, reserves the same space not only on the side where the scrollbar actually appears, but mirrored on the opposite side as well. This is especially helpful for centered content that should visually stay exactly in the middle of the viewport: without both-edges, a scrollbar appearing on the right would nudge the content slightly to the left, because space is only reserved on one side.
In practice, both-edges fits mainly modal dialogs or centered layout containers, where a visual shift is noticed immediately, while for regular page content, whose left edge is already aligned to the viewport edge anyway, plain stable is usually entirely sufficient.
/* Centered modal content stays visually centered,
even when a scrollbar appears on the right */
html {
scrollbar-gutter: stable both-edges;
}
4. Differences between operating systems: overlay vs. classic scrollbars
How noticeable a layout shift is at all depends heavily on the operating system and its scrollbar style. macOS shows a semi transparent overlay scrollbar by default, which floats over the content and takes up no space, meaning the classic problem often does not show up at all under many configurations. Windows and most Linux desktop environments, on the other hand, show a classic, space consuming scrollbar that actually shrinks the available area.
These differences make scrollbar-gutter: stable a safeguard that often stays invisible on macOS but makes a noticeable difference on Windows and Linux. Anyone testing only on a macOS device can easily miss the problem, which is why testing under Windows, or with a forced classic scrollbar style, is recommended before launching a new layout.
5. Combining with overflow: when scrollbar-gutter actually takes effect
scrollbar-gutter only affects elements that are potentially scrollable, meaning they have an overflow value other than visible, usually auto, scroll, or hidden combined with additional scrolling controlled through JavaScript. On an element with overflow: visible, the property has no effect, because such an element by definition never shows a scrollbar of its own.
Most commonly, scrollbar-gutter is used together with overflow-y: auto on the html or body element, to stabilize the global page scrollbar, but the combination works exactly the same on individual containers like a sidebar menu, a scrollable modal body, or a long product variant list that scrolls independently of the rest of the page.
/* The global page scrollbar gets reserved space,
so switching between short and long pages
no longer changes the content width */
html {
overflow-y: auto;
scrollbar-gutter: stable;
}
6. A typical bug: modal opens, background content jumps sideways
A particularly common use case is opening a modal that sets overflow: hidden on the body element via JavaScript to prevent background scrolling. Without scrollbar-gutter, the page's scrollbar disappears completely at that moment, sliding the entire page content to the right by its width, visible as a short but jarring jump of the navigation, logo and content when the modal opens, and again when it closes.
With scrollbar-gutter: stable permanently set on the html element, the reserved space stays in place even while overflow: hidden is active and the bar itself becomes invisible, because the property keeps the space free regardless of the actual overflow value, as long as overflow is not visible. The jump on opening and closing modals disappears completely, with no JavaScript workaround measuring widths manually required.
7. Measuring layout shift: DevTools and the Web Vitals extension
Whether a scrollbar related layout shift is actually happening can be verified in Chrome DevTools through the Performance tab and the Layout Shift entries logged there, which show exactly the affected moment and the elements that shifted. The free Web Vitals browser extension additionally shows a page's current CLS value in real time and visually highlights which elements moved.
For a targeted test, it helps to load a page or list right above and right below the threshold where a scrollbar appears, for example by adding or removing a single list item, and watch whether elements outside the scrolling container visibly move. If the layout stays stable in both cases, scrollbar-gutter is working as intended.
8. Browser support and a harmless fallback for older browsers
Chrome, Edge and Firefox support scrollbar-gutter reliably in current versions, Safari caught up with a more recent version, so the property has by now arrived in every major browser engine. A browser that does not know the property simply ignores the declaration and falls back to the classic, layout shifting behavior, with no errors or unexpected side effects, because scrollbar-gutter is purely additive and does not override any other property.
That makes adoption risk free: there is no reason to wait for an @supports feature flag or a JavaScript detection before using scrollbar-gutter: stable in production. For users on a non-supporting browser, nothing changes compared to the already familiar previous behavior, while users on a supporting browser immediately benefit from a more stable layout.
9. Practical use in a shop: category pages, filter lists and checkout
In a Magento and Hyvä context, scrollbar-gutter: stable pays off particularly in three places: the global html level against jumps when opening cart or filter modals, scrollable filter lists in category navigation whose length varies depending on the selected filters, and scrollable areas in checkout, for example a long payment method or shipping option list, where a layout shift during a critical conversion step would be especially damaging.
Implementing it in Tailwind costs only a single utility class or a short line in the CSS layer and requires no extra JavaScript, no manual width measurement, and no adjustment to existing Alpine.js components. Given the low implementation effort against the noticeable gain in stability, scrollbar-gutter: stable belongs in practically every modern layout with potentially scrollable areas.
| Value | Reserved space | When it makes sense | Effect when the bar appears |
|---|---|---|---|
auto (default) |
None | When layout shift is tolerated | Content width visibly shrinks |
stable |
One side, permanent | Scrollable containers, page scroll | No shift, bar appears inside the gutter |
stable both-edges |
Both sides, permanent | Centered layouts, modals | No shift, content stays exactly centered |
| Overlay scrollbar (macOS) | No physical space needed | System dependent, not controllable | Usually no shift anyway |
Mironsoft
Modern CSS, layout architecture and rendering performance
CSS that stays maintainable instead of breaking with every change?
We review existing stylesheets for specificity chaos and layout thrashing, then build a CSS architecture with cascade layers, custom properties and modern layout primitives that still makes sense after the tenth feature.
CSS Audit
Systematically uncovering specificity issues, cascade conflicts and unused selectors.
Architecture Refactoring
Introducing cascade layers, custom properties and design tokens cleanly.
Performance Tuning
Fixing layout thrashing, expensive selectors and rendering bottlenecks.
10. Summary
scrollbar-gutter: The Essentials at a Glance
Core idea
scrollbar-gutter: stable permanently reserves the space a scrollbar would take, independent of whether the bar is currently visible.
both-edges
stable both-edges reserves space on both sides and keeps centered content exactly centered even when the bar appears.
OS difference
macOS often uses space saving overlay scrollbars, Windows and Linux show classic, space consuming bars, so testing on multiple systems matters.
Prerequisite
scrollbar-gutter only works together with overflow other than visible, usually auto, scroll, or JavaScript controlled hidden.