Prevent layout shift when toggling scrollbar on Window
- Published on
- • 3 mins read
When will the scrollbar toggle? For example:
- Open a
Modal
,Popup
, orDrawer
with a lot of content and prevent the user from scrolling theWindow
. - Toggle an
Accordion
or aTab
which expands the document height that leads to shows up the scrollbar. - ...
On Window devices, these cases will cause the layout shift. This is because the scrollbar is added to the Window
which makes the Window
's width smaller. This experience is not good for the user.
So let's prevent this layout shift with CSS.
The classic fix
html {
overflow-y: scroll;
}
The classic fix is to add the overflow-y: scroll
to the html
element. This will always show the scrollbar on the Window
(even if the content's height is smaller than the viewport's height).
The scrollbar in this case will always be visible. And its background turns to gray (if the Window
isn't scrollable).
And of course, I don't recommend this solution cause I think it looks bad as the original problem.
Using view width
A better solution is to add an invisible margin-left
to the html
element with the same width as the scrollbar. This margin-left
will be visible when the scrollbar is added to the Window
and invisible when the scrollbar is removed from the Window
.
But how to get the scrollbar's width ?
The answer is to use the vw
unit.
If you don't know yet, vw
or view width is a CSS unit just like px
, %
, or rem
but it's relative to the viewport's width. 100vw
is equivalent to 100%
of the viewport's width (including the scrollbar), and 100%
width (for the html
element) is equivalent to 100% of the viewport's width (without the scrollbar)
So, we can calculate the width of the scrollbar by subtracting the 100%
width from the 100vw
width with the CSS's calc()
function like this:
html {
margin-left: calc(100vw - 100%);
}
The margin-left
value will equal 0
when the Window
isn't scrollable and equal to the scrollbar's width when the Window
is scrollable.
Note
If you use this way to prevent layout shift and your application has a fixed
's element (like a Popup or a Modal) which prevents Window scroll with the overflow-y: hidden
style when it's open, you should also add the margin-left
to the fixed
element.
For example:
html,
.popup-overlay {
margin-left: calc(100vw - 100%);
}
Another solution is to set the width of the html
element to 100vw
and prevent horizontal scroll:
html {
width: 100vw;
overflow-x: hidden;
}
This solution only makes sense if your application doesn't have to scroll horizontally (like a blog or a documentation website).
And I'm using this in my blog (you can open the devtool
and check the html
styles to see it ).
The no-code way
There are 2 ways to prevent layout shift without writing any CSS code:
The first one is to tell your users not to use Window device and to use a Mac or a Linux device instead
The second one is to just... leave it as it is, sometimes it's not a big deal, and your user doesn't actually care about this layout shift
If you have any other solutions, please let me know in the comments below.
Happy styling