# Taming the Scrollbar Shift

Created: 2025-04-10

2 min read

CSS

Web Performance

Layout

## Table of Contents

* [The Problem](#the-problem)
* [Solution 1: The Modern Way with scrollbar-gutter](#solution-1-the-modern-way-with-scrollbar-gutter)
* [Solution 2: The Math Approach](#solution-2-the-math-approach)
* [Solution 3: The Tailwind CSS 4 Native Way](#solution-3-the-tailwind-css-4-native-way)
* [My Take](#my-take)

A couple of months ago I noticed on my Windows computer that I noticed content layout shifts when navigating through this website. At first I did not understand what caused it, and more importantly, why. In the end it was because some pages would have enough content so a scrollbar would be shown while others did not and therefore switching between either would cause Content Layout Shift (CLS). That's the infamous scrollbar layout shift, and it's been driving developers crazy for years.

## [The Problem](#the-problem)

On Windows, Chrome's scrollbars take up actual space in the viewport (unlike on macOS where they overlay content). When content becomes long enough to scroll, the scrollbar appears and poof - your layout shifts by about 17px. Buttons move, text reflows, and your pixel-perfect design goes out the window.

## [Solution 1: The Modern Way with scrollbar-gutter](#solution-1-the-modern-way-with-scrollbar-gutter)

CSS now has a property specifically designed for this problem:

CSS

Copy

```css
body {
    scrollbar-gutter: stable;
}
```

This reserves space for the scrollbar even when it's not visible. Clean, simple, and elegant! But... browser support isn't perfect yet (though it's getting better). For Windows Chrome this would however always show the scrollbar even if there is nothing to scroll.

Another issue with this approach is that when you use Tailwind (you should!), it means quite a lot of changes to `globals.css` which is something I did not want to do just to resolve this issue.

## [Solution 2: The Math Approach](#solution-2-the-math-approach)

You can calculate and account for scrollbar width:

CSS

Copy

```css
.container {
    width: calc(100% - 17px); /* Approximate scrollbar width */
    margin-right: auto;
    margin-left: 0;
}
```

This works but feels a bit hacky, and the exact scrollbar width can vary between operating systems and browsers.

## [Solution 3: The Tailwind CSS 4 Native Way](#solution-3-the-tailwind-css-4-native-way)

Since Tailwind CSS 4 is CSS-first, I no longer need a plugin or a separate Tailwind config file for this. A tiny utility in `globals.css` is enough to get the same result.

Here is the utility:

CSS

Copy

```css
@utility scrollbar-none {
    scrollbar-width: none;
    -ms-overflow-style: none;
}

.scrollbar-none::-webkit-scrollbar {
    display: none;
}
```

## [My Take](#my-take)

I have found this to be the cleanest Tailwind approach. It keeps the implementation local to CSS, avoids extra dependencies, and applying the `scrollbar-none` class to the root layout is enough.