Scrollbar width custom event
Some operating systems and browsers are not showing scrollbars by default. That often results in developers forgetting about these pesky gray bars and the issues they can cause.
I'll give you two quick examples:
overflow: hidden on the body element, if there was a scrollbar visible, content will jump a little as it now has more space. If you ever implemented scroll locking for modals, you've probably encountered this issue.
Another thing is that
width: 100vw and
width: 100% on the body element don't match if there is a scrollbar visible:
100vwis the width of the viewport including the scrollbar.
100%is the width of the viewport excluding the scrollbar.
This becomes obvious if you have a fixed element like a header. It will be a little bit wider than the rest of the content when scrollbar is visible.
I'm sure there are more issues, but these are the two I remembered on top of my head. Anyhow, let's see how to solve this.
Ideally we would like to have a
scrollbar-width event. It doesn't exist, so we'll have to create a custom event ourselves, and trigger it when scrollbar width changes.
To catch the width changing, we can't use the
resize event because viewport size don't change when scrollbar is toggled.
However, if we set the ResizeObserver on the
html element, it will trigger when the scrollbar is toggled.
After setting the observer we need to fire our custom event when width has changed. Code looks something like this:
Here is an example of how to use it to update
--scrollbar-width CSS variable:
// Initialize our custom event stuff ; ; // Update the variable on the first load ; initialWidth; // Start listening for changes "scrollbar-width",;
Similarly to when we track the scroll position (or window size), we'll have to set the initial state on load. Then, we can add a listener and make sure that the local state is up to date.
This all happens on the client. Which means that
Here is a live demonstration. Click on the button below to toggle the vertical scrollbar.
Please note that if your browser doesn't show scrollbars, width will always be zero.