If an element is set to width: 100vw; and there is a vertical scrollbar the width of the element will be equal to the viewport plus the width of the scrollbar.<
This is a more full-fledged approach to the bug since it still exists in modern browsers. Setting overflow-x: hidden can cause problems or be undesirable in many situations.
A full example is available here: http://codepen.io/bassplayer7/pen/egZKpm
My approach was to determine the width of the scroll bar and use calc() to reduce the 100vw by the amount of the scroll bar. This is a little more complicated because in my case, I was pulling the width of the content out from a box that had a defined with so I needed to declare the margin as well.
A few notes regarding the code below: first, I noticed that 20px seems to be a rather broad magic number for the scroll bars. I use a SCSS variable (it doesn't have to be SCSS) and code outside of @supports as a fallback.
Also, this does not guarantee that there will never be scroll bars. Since it requires Javascript, users that don't have that enabled will see horizontal scroll bars. You could work around that by setting overflow-x: hidden and then adding a class to override it when Javascript runs.
Full SCSS Code:
$scroll-bar: 20px;
:root {
--scroll-bar: 8px;
}
.screen-width {
width: 100vw;
margin: 0 calc(-50vw + 50%);
.has-scrollbar & {
width: calc(100vw - #{$scroll-bar});
margin: 0 calc(-50vw + 50% + #{$scroll-bar / 2});
}
@supports (color: var(--scroll-bar)) {
.has-scrollbar & {
width: calc(100vw - var(--scroll-bar));
margin: 0 calc(-50vw + 50% + (var(--scroll-bar) / 2));
}
}
}
Convert the above to plain CSS just by removing #{$scroll-bar} references and replacing with the px value
Then this Javascript will set the CSS Custom Property:
function handleWindow() {
var body = document.querySelector('body');
if (window.innerWidth > body.clientWidth + 5) {
body.classList.add('has-scrollbar');
body.setAttribute('style', '--scroll-bar: ' + (window.innerWidth - body.clientWidth) + 'px');
} else {
body.classList.remove('has-scrollbar');
}
}
handleWindow();
As a side note, Mac users can test this by going to System Preferences -> General -> Show Scroll Bars = Always