100vw causing horizontal overflow, but only if more than one?
Say you have this:
html, body {margin: 0; padding: 0}
.box {width: 100vw; height: 100vh}
<div class="box">Screen 1</div>
You'll get something that fills the screen, no scrollbars. But add another:
<div class="box">Screen 1</div>
<div class="box">Screen 2</div>
You get not only vertical scrollbars (expected), but a slight horizontal scroll.
I realize you could omit the width, or set it to width: 100%, but I'm curious why this is happening. Isn't 100vw supposed to be "100% of the viewport width"?
Solution 1:
As already explained by wf4, the horizontal scroll is present because of the vertical scroll. which you can solve by giving max-width: 100%
.
.box {
width: 100vw;
height: 100vh;
max-width:100%; /* added */
}
Working Fiddle
Solution 2:
scrollbars will be included in the vw
so the horizontal scroll will be added to allow you to see under the vertical scroll.
When you only have 1 box, it is 100% wide x 100% tall. Once you add 2, its 100% wide x 200% tall, therefore triggering the vertical scrollbar. As the vertical scrollbar is triggered, that then triggers the horizontal scrollbar.
You could add overflow-x:hidden
to body
html, body {margin: 0; padding: 0; overflow-x:hidden;}
.box {width: 100vw; height: 100vh; background-color:#ff0000}
.box2 {width: 100vw; height: 100vh; background-color:#ffff00}
http://jsfiddle.net/NBzVV/
Solution 3:
I had a similar problem and came up with the following solution using JS and CSS variables.
JS:
function setVw() {
let vw = document.documentElement.clientWidth / 100;
document.documentElement.style.setProperty('--vw', `${vw}px`);
}
setVw();
window.addEventListener('resize', setVw);
CSS:
width: calc(var(--vw, 1vw) * 100);
1vw is a fallback value.
Solution 4:
Update: As of Chrome version 66, I cannot reproduce the behaviour reported by question anymore. No workaround appears to be needed.
Original Answer
This is actually a bug as reported in this answer and the comments above.
While the workaround in the accepted answer (adding .box {max-width: 100%;}
) generally works, I find it noteworthy that it does not currently work for display:table
(tested in Chrome). In that case, the only workaround I found is to use width:100%
instead.
-
Broken Fiddle with
display:table
-
Working Fiddle with
display:table
andwidth:100%