CSS scrollbar-gutter Property
The scrollbar-gutter property allows developers to reserve space for the scrollbar, preventing annoying layout shifts when content grows.
| auto | The default behavior where the gutter is only present if the scrollbar is currently visible. |
| stable | Reserves space for the scrollbar even if the content does not overflow the container. |
| both-edges | Used in conjunction with stable to reserve space on both the start and end edges for layout symmetry. |
Code Examples
A basic example showing how the stable value reserves space for the scrollbar gutter even when content fits within the height.
<div style="width: 300px; height: 100px; overflow-y: auto; scrollbar-gutter: stable; border: 1px solid #333333;">
<p>The space on the right is reserved even though there is no scrollbar yet.</p>
</div>An advanced example using stable both-edges and JavaScript to demonstrate layout stability when content is added dynamically.
<style>
.container {
width: 400px;
max-height: 200px;
overflow-y: auto;
scrollbar-gutter: stable both-edges;
background-color: #f4f4f4;
padding: 10px;
text-align: center;
}
</style>
<div id="box" class="container">
<p>This content stays perfectly centered.</p>
</div>
<button onclick="addContent()">Add More Content</button>
<script>
function addContent() {
const box = document.getElementById("box");
box.innerHTML += "<p>Adding more lines to trigger the scrollbar without shifting the layout.</p>";
box.style.backgroundColor = "#e0e0e0";
}
</script>Pro Tip
Pair scrollbar-gutter: stable with overflow-y: auto. This combination ensures that the scrollbar only appears when it is actually needed for navigation, but the layout remains rock solid and shift-free because the space was already allocated from the start.
Deep Dive
Think of your content like a crowd in a hallway. When a scrollbar appears, it acts like a wall suddenly moving inward, forcing everyone to shift over. This is known as layout shift, and it can be jarring for users. The scrollbar-gutter property tells the browser to build that wall ahead of time and leave it there, whether the scrollbar is actually present or not. By reserving this space, your content stays locked in position. This property specifically targets classic scrollbars that occupy physical space in the layout, rather than overlay scrollbars often seen on mobile devices or macOS, which float over the content without pushing it.
Best Practices
Apply this property to high-level containers or the body when dealing with dynamic content that might trigger a scrollbar. Use the stable value to ensure the gutter is always present. If you have centered designs where visual balance is critical, use the stable both-edges values to ensure the content remains perfectly centered by placing a gutter on both sides of the container.
Common Pitfalls
The most common confusion is why nothing happens on devices with overlay scrollbars. If the operating system or browser uses scrollbars that float over content, they do not occupy space, so there is no gutter to reserve. Also, remember that both-edges only works when combined with the stable keyword.
Accessibility
Layout shifts can be more than just annoying; they can cause users with motor impairments to misclick or lose their place. By providing a stable gutter, you ensure a consistent interface that does not move unexpectedly, contributing to a more accessible and professional user experience.
Dev Data Table: scrollbar-gutter property
| default | auto |
| animatable | no |
| inherited | no |
| experimental | no |
| year_intro | 2020 |
| year_standard | 2021 |
| js_syntax_1 | element.style.scrollbarGutter |
| js_syntax_2 | element.style.setProperty("scrollbar-gutter", "stable") |
| js_note | Use camelCase scrollbarGutter when accessing via the style object in JavaScript. |
| browsers | { "Chrome": 94, "Edge": 94, "Firefox": 97, "Safari": 18.2, "Opera": 80, "Chrome Android": 94, "Safari on iOS": 18.2, "Samsung Internet": 17, "Opera Mobile": 66 } |