Prevent Layout Shifts with CSS scrollbar-gutter: stable

This article provides an overview of the CSS scrollbar-gutter: stable property, examining how unexpected layout shifts occur when scrollbars appear and how this modern CSS feature permanently eliminates them. You will learn the mechanics behind the "scrollbar jump," how scrollbar-gutter: stable reserves space in the viewport, and how to implement it to improve visual stability and user experience across your web pages.

The Problem: The "Scrollbar Jump" and Layout Shifts

When a user navigates between a short page that fits entirely within the viewport and a longer page that requires scrolling, browsers typically insert a vertical scrollbar. On operating systems configured with classic (non-overlay) scrollbars—such as default Windows setups—this scrollbar occupies physical space, typically between 12 and 17 pixels.

Because the viewport's available width shrinks by the width of the scrollbar, centered elements, full-width grids, and text re-flow instantly. This jarring visual snap is known as a layout shift. It harms user experience and can negatively impact Cumulative Layout Shift (CLS), a Core Web Vital metric used by search engines to evaluate page stability.

Historically, developers addressed this using overflow-y: scroll, which forces a persistent scrollbar on every page. While this stops the jumping, it introduces an undesirable, inactive scrollbar track on pages that do not have enough content to scroll.

What is scrollbar-gutter: stable?

The scrollbar-gutter property provides direct control over the presence of the space reserved for a scrollbar.

When set to stable, the browser reserves a gutter—an empty strip equal to the width of the scrollbar—along the scrolling edge of the container, even when the content does not overflow.

html {
  scrollbar-gutter: stable;
}

By applying this rule to the root html element, the document layout width remains identical whether the page requires scrolling or not. When content expands or when the user navigates to a longer page, the scrollbar simply renders inside the already-reserved space without pushing or reflowing surrounding elements.

How It Works in Practice

Default Behavior (scrollbar-gutter: auto)

By default, the browser only allocates space for a scrollbar when content overflows its container. If content is short, no gutter exists. When content grows beyond the container height, the layout width decreases to make room for the scrollbar.

Stable Behavior (scrollbar-gutter: stable)

With stable, the gutter is permanently present as long as the element could potentially scroll (i.e., overflow is set to auto, scroll, or left to standard document behavior).

  • If content does not overflow: The gutter remains empty, preserving the layout's width.
  • If content overflows: The scrollbar occupies the pre-existing gutter. The layout width does not change, and zero layout shift occurs.

Symmetrical Spacing (scrollbar-gutter: stable both-edges)

If your layout relies on strict visual symmetry, having a reserved gutter only on the right edge might make centered content appear slightly off-center on pages without an active scrollbar. You can pass the optional both-edges keyword to mirror the reserved space on the opposite side:

html {
  scrollbar-gutter: stable both-edges;
}

This creates an identical gutter on both edges of the container, ensuring that perfectly centered elements remain centered relative to the viewport.

Key Advantages Over Older Techniques

  1. Clean Visuals: Unlike overflow-y: scroll, scrollbar-gutter: stable does not render a disabled or empty scrollbar track; it simply reserves empty space.
  2. Overlay Scrollbar Awareness: On platforms with overlay scrollbars (such as macOS or mobile devices), overlay scrollbars float above content and do not occupy layout space. The scrollbar-gutter property recognizes this and will not reserve unnecessary space if the user's system does not use classic scrollbars.
  3. Component-Level Use: The property is not limited to the root element. It can be applied to modals, sidebars, data tables, and dropdown menus to prevent internal container jumping as dynamic data loads.

Browser Support and Progressive Enhancement

The scrollbar-gutter property is supported in all modern major browsers, including Chromium-based browsers (Chrome, Edge), Firefox, and Safari. Because unsupported browsers simply ignore unknown CSS properties and fall back to standard scrollbar behavior, scrollbar-gutter: stable can be implemented safely as a progressive enhancement to eliminate layout shifts immediately.