This content originally appeared on Bram.us and was authored by Bramus!
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 aims to give us developers more control over that.
Let’s take a look.
~
?? The CSS features described in this post are still experimental and only supported in Chromium 88+ with the #experimental-web-platform-features
flag enabled through chrome://flags
.
? To keep your primary Chromium install clean, I recommend you do not set this flag in Chromium Stable, but resort to Beta / Canary builds.
~
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”:
Using 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: stable;
The scrollbar-gutter
property aims to solve the problem described above.
By setting scrollbar-gutter
to 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 overflow
property.
The default value for scrollbar-gutter
is auto
. With this value set, the behavior is unchanged from the one described in The Problem
~
# Keeping things symmetric with both-edges
A 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 mirror
. The experimental implementation in Chromium still uses this old name.
~
# Caveats
There are only two small caveats with this one:
- As for the
overflow
property, ascrollbar-gutter
set on the root element is applied to the viewport instead. - Unlike the
overflow
property, the browser will not propagatescrollbar-gutter
from the HTMLbody
element.
~
# Browser Support
scrollbar-gutter
is not supported in any browser at the time of writing. Chromium has released an “Intent To Ship” just last week, so I expect it to land in Chromium unflagged pretty soon. Other browser vendors are sending positive signals towards this addition, so they’ll follow too.
To follow along, here are the relevant Tracking Bugs:
~
# In Summary
With the 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
? https://t.co/AKrkhuHTPX
? #css #scrollbar pic.twitter.com/djPRHEXXMv
~
? Like what you see? Want to stay in the loop? Here's how:
This content originally appeared on Bram.us and was authored by Bramus!
Bramus! | Sciencx (2021-07-23T00:33:28+00:00) Prevent unwanted Layout Shifts caused by Scrollbars with the scrollbar-gutter CSS property. Retrieved from https://www.scien.cx/2021/07/23/prevent-unwanted-layout-shifts-caused-by-scrollbars-with-the-scrollbar-gutter-css-property/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.