DEV Community

Cover image for Preventing the Layout Shift Caused by Scrollbars
Rashid Shamloo
Rashid Shamloo

Posted on

Preventing the Layout Shift Caused by Scrollbars

The Problem

When content overflows the page and the scrollbar shows up, the content is pushed/shifted to the left and vice versa, when the scrollbar disappears, the content is pushed/shifted to the right:

This annoying layout shift can be prevented in multiple ways. In this article, I will go over them one by one:

1. Always showing the scrollbars

This is the easiest and ugliest solution.

body {
  overflow-y: scroll;
}
Enter fullscreen mode Exit fullscreen mode

2. The scrollbar-gutter property

The scrollbar-gutter property has been made for this exact purpose. setting it to stable will preserve the space for the scrollbar and prevent the layout shift.

html {
  scrollbar-gutter: stable;
}
Enter fullscreen mode Exit fullscreen mode

BUT... it doesn't work in Safari and the scrollbar track will always be visible on your page which is not desirable.

*. A little note about 100vw and 100%

Before continuing to the next points, it is necessary to understand the difference between 100vw and 100%:

  • 100vw : Full width including the scrollbar.
  • 100% : Full width excluding the scrollbar.

3. Shifting the content to the right

When the scrollbar is not showing, 100vw and 100% are equal, and when the scrollbar is showing, the difference between them is equal to the width of the scrollbar.

So if we shift the content to the right by the difference of 100vw and 100%, we can prevent the layout shift. To achieve it we can use padding-left on the parent/container element:

.container {
  padding-left: calc(100vw - 100%);
}
Enter fullscreen mode Exit fullscreen mode

Source

4. Positioning inside a 100vw width parent

Since scrollbars don't affect the vw unit, we can fix the problem by setting the width of the parent/container in the vw unit and centering/positioning our elements inside of it:

.container {
  width: 100vw;
  /* elements inside won't be affected by scrollbars */
  display: flex;
  align-items: center;
  justify-content: center;
}
Enter fullscreen mode Exit fullscreen mode

Source


The result after applying the 4th method:

Top comments (4)

Collapse
 
mrmg profile image
Michael Geil

In a few cases, display: flex; can destroy the entire layout.
padding-left can be ineffective if the white space on the left side is too large.
I tried this rule:

.container {
   position: relative;
   left: calc((100vw - 100%) / 2);
}
Enter fullscreen mode Exit fullscreen mode

The result was as desired. A stable layout with or without scrollbar.

Collapse
 
fruntend profile image
fruntend

Сongratulations 🥳! Your article hit the top posts for the week - dev.to/fruntend/top-10-posts-for-f...
Keep it up 👍

Collapse
 
rashidshamloo profile image
Rashid Shamloo

Thanks for featuring my article :)

Collapse
 
oahmada profile image
Adam Hao

It seems impossible to prevent content shifting and horizontal scrollbar appearing at the same time.