A side-effect when showing scrollbars on the web is that the layout of the content might change depending on the type of scrollbar. The
scrollbar-gutter CSS property —which will soon ship with Chromium — aims to give us developers more control over that.
Let’s take a look.
Table of Contents
# Classic vs. Overlay Scrollbars
Before we jump in, there’s a distinction between two types of scrollbars that we need to make.
# Overlay Scrollbars
Overlay Scrollbars are those iOS/macOS-style scrollbars which are placed over the content. They are not shown by default, but only while the user is scrolling. To keep the content underneath visible they are semi-transparent, but that’s totally up to the user-agent (browser) to determine. While interacting with them, their size may also vary.
Figure: An Overlay Scrollbar is placed over the content.
# Classic Scrollbars
Classic Scrollbars are scrollbars that are placed in the so-called “Scrollbar Gutter”. The Scrollbar Gutter is the space between the inner border edge and the outer padding edge. With classic scrollbars, the size of the Scrollbar Gutter is the same as the width of the scrollbar. These scrollbars are usually opaque (not transparent) and take away some space from the adjacent content.
Figure: A Classic Scrollbar takes away some space from the adjacent content.
🍏 macOS User? You can switch from Overlay to Classic Scrollbars via System Preferences!
If you’re a macOS user you can switch from Overlay to Classic Scrollbars via System Preferences → General. Set “Show scroll bars” to “Always”:
defaults you can also enable it:
defaults write NSGlobalDomain AppleShowScrollBars -string "Always"
Some applications — such as Chrome — need to be restarted after changing the setting.
# The Problem
When the content of a box becomes too big (e.g. when it is overflowing), the browser will — by default — show a scrollbar. In case of a classic scrollbar this has a nasty side-effect: as the scrollbar needs some space, the available width for the content shrinks — thus the layout shifts.
Figure: As the scrollbar gets shown, the content shifts.
☝️ In case of Overlay Scrollbars there’s no layout shift, as those scrollbars get rendered over the content.
# The Solution:
scrollbar-gutter property aims to solve the problem described above.
stable we can have the UA always show the Scrollbar Gutter, even if the box is not overflowing and no scrollbar is shown. This way we have a visually stable layout: when the box starts to overflow the scrollbar will be rendered but no layout shift will happen as space for it was already reserved.
Figure: As the scrollbar gets shown, the content does not shift as the browser had already reserved space for the scrollbar gutter.
When the scrollbar gutter is present but the scrollbar is not, the background of the scrollbar gutter is painted as an extension of the padding.
Note that this
scrollbar-gutter property has no effect on the rendering of the scrollbar itself — it only affects the rendering of the gutter. The rendering of the scrollbar is controlled by the
The default value for
auto. With this value set, the behavior is unchanged from the one described in The Problem
# Keeping things symmetric with
scrollbar-gutter value of
stable can be extended with
both-edges. By setting
scrollbar-gutter: stable both-edges; you can achieve symmetry. As per spec:
If a scrollbar gutter would be present on one of the inline start edge or the inline end edge of the box, another scrollbar gutter must be present on the opposite edge as well.
Figure: As the scrollbar gets shown, the content does not shift. Above that the same gutter space was reserved on the opposite edge.
In a previous version of the spec
both-edges was named
There are only two small caveats with this one:
- As for the
scrollbar-gutterset on the root element is applied to the viewport instead.
- Unlike the
overflowproperty, the browser will not propagate
scrollbar-gutterfrom the HTML
# Browser Support
💡 Although this post was originally published in July 2021, the section below is constantly being updated. Last update: Jan 13, 2023.
Here is an up-to-date list of browser support for CSS
- Chromium (Blink)
✅ Available in Chromium 94 and up.
Experimental support first appeared in Chromium 88.
- Firefox (Gecko)
✅ Available in Firefox 97 and up.
- Safari (WebKit)
❌ No support
The pen embedded below will indicate if the browser you are currently using supports
scrollbar-gutter or not:
See the Pen CSS scrollbar-gutter Support test by Bramus (@bramus) on CodePen.
To stay up-to-date regarding browser support, you can follow these tracking issues:
- Blink/Chromium: Issue #710214 – Open
- Gecko/Firefox: Issue #1715112 – Closed
- WebKit/Safari: Issue #167335 – New
# In Summary
scrollbar-gutter we can prevent some unwanted layout changes caused by scrollbars. The graphic below summarizes the scenarios covered in this post:
If your browser supports
scrollbar-gutter, you can also check out this CodePen demo:
See the Pen CSS scrollbar-gutter demo by Bramus (@bramus) on CodePen.
To help spread the contents of this post, feel free to retweet the announcement tweet:
Prevent unwanted Layout Shifts caused by Scrollbars with the `scrollbar-gutter` CSS property— Bram.us (@bramusblog) July 23, 2021
🏷 #css #scrollbar pic.twitter.com/djPRHEXXMv
🔥 Like what you see? Want to stay in the loop? Here's how:
great post 🤘💀
Leave a comment