linkedlist:

Avoid "width: 100vw" in CSS

#47 · (updated 2022-07-08) · CSS, compatibility

Setting an element's width to 100vw makes it as wide as the current viewport. But doing that is bad practice. First, it is almost always unnecessary. A block element, by default, already takes up all the available width. Setting the width manually is not needed in that situation. Second, it may result in unnecessary horizontal scrolling as the page is wider than the visible view port width.

The vw unit in CSS is defined as being 1% of the viewport's width. But that is only half the story. 100% and 100vw are not exactly the same, even when being used on root elements. Setting a width in percentages usually refers to the ancestor element. width:100% would make the element exactly as wide as its ancestor. The vw unit, however, refers to the viewport width.

Viewport

The viewport is the area of the currently visible content of a website. Content outside the viewport is not visible. But it can be scrolled into the viewport to make it visible.

The concept of the viewport is nothing new. But its semantics have changed slightly due to the introduction of new features or change in behaviour of browsers. For example, the address bar may be hidden when a user scrolls. Or the application may switch to full screen mode after an interaction. Or a scrollbar appears or disappears. All of these events may change the size of the viewport.

The Problem

There are different ways to display scroll bars. Traditionally they were always visible and the scroll bar area was not part of the actual website. Especially in mobile browsers, that is different. There the scroll bars usually only appear while scrolling, and they overlap the websites' content. Today, it depends on the users' operating system, browser, and configuration how a scroll bar is being displayed.

Unfortunately, it was not specified whether the viewport-percentage lengths like vw should include those parts of the browser that may expand or retract. That also applies to scroll bars. Hence, different browsers implement that differently.

And now we get to the actual problem. In some browsers, the viewport width includes the scroll bar. When using width: 100vw in browsers that are configured to show a full scroll bar, that evaluates to the width of the visible website plus the scroll bar width. But an element with that width is actually wider than what is visible in the browser's viewport. So you will get completely unnecessary horizontal scrolling. It does not matter how small or large the browser window is, there is always a scroll bar to scroll by exactly the width of the scroll bar.

That is not a browser implementation bug, though. The specification is just not clear and from an implementors view, there are pros and cons in either way. The solution to this problem is simple, though. Do not use width: 100vw unless you absolutely know what you are doing. Usually, you can just remove that declaration from your CSS and everything will actually work.

This issue can be observed on several operating systems and multiple browsers. An example is Firefox on macOS. You can test it if you open the System Preferences and change the "Show scroll bars" setting within "General".

Viewport Units in the Future

This issue is known and there are changes in the specification that are meant to solve it. The spec now defines different sizes of the viewport. In addition to the UA-default viewport (vw), there are now also the large viewport (lvw) and the small viewport (svw). While some browsers already support (some of) these, the situation regarding scroll bars has not been answered conclusively.

Level 3 assumes scrollbars never exist because it was hard to implement and only Firefox bothered to do so. This is making authors unhappy. Can we improve here?
Source