CSS 100vw paradox

Anand Siddharth
Mounty engineering
Published in
3 min readOct 21, 2021

Ever used 100vw in your viewport and seen horizontal scrollbars appearing at the bottom of your screen?

Well if you are using Mac and no external pointing device is connected you might not able to identify the above issue!
Because in Mac, scrollbar visibility is set to Automatic, so when no external mouse is connected, scrollbars would appear only when while scrolling. But in case you are using the external mouse the scrollbar is shown always! you will be able to change these settings on System Preferences > General.

Is scrollbar visibility the problem?

Yes! If you are using windows system the scrollbars are always visible and 100vw to your container will overflow the browser window! This is because the vertical scrollbar on your right has a width (appx. 15px) so for example, your available viewport width is 1000px and your scrollbars are visible, then actually available viewport width is (1000–15) i.e. 985px.

So here’s a screenshot from media query tester website:

So when you specify 100vw browser computes the value and sets it to 1000px instead of 985px. But why?

The viewport-percentage lengths are relative to the size of the initial containing block. When the height or width of the initial containing block is changed, they are scaled accordingly. However, any scrollbars are assumed not to exist. — Source: CSSWG

How to solve it?

Well, there would be multiple ways! Some good, Some Makeshifters!
One of the best solutions I found was by Jonnie Hallman in his article.
He interestingly solved this problem using javascript!

Here’s the solution:

How did it work?

In the above example, I have written a init function that gets the document’s client width and sets it to :root with variable name --viewport-width, And then used it everywhere in CSS where needed.
In the above example, I have also demonstrated a use case where there's a div wrapper in line 14 whose width is explicitly set to 500px, and its child element div.inner-container is set to width: calc(var(--viewport-width) / 2), even though its parent element is 500px the div is exactly half the client’s width.

Here’s a beautiful example of the difference between client width and inner width by Martin Michálek https://codepen.io/machal/pen/rrXNWO

About Mounty

Mounty is an online discovery and booking platform for camps, adventure activities & trips anchored by the largest network of privately owned campsites, adventures, and trips providers. We aim to make the travel experience fun and seamless. We do this through an amazing team of passionate travelers with years of experience and exceptional capabilities.

Thanks! For reading. Hope you found this interesting!

--

--