100vw causando desbordamiento horizontal, pero solo si hay más de uno?

97

Di que tienes esto:

html, body {margin: 0; padding: 0}
.box {width: 100vw; height: 100vh}

<div class="box">Screen 1</div>

Obtendrá algo que llena la pantalla, sin barras de desplazamiento. Pero agrega otro:

<div class="box">Screen 1</div>
<div class="box">Screen 2</div>

Obtiene no solo barras de desplazamiento verticales (esperado), sino un ligero desplazamiento horizontal.

Me doy cuenta de que podría omitir el ancho o establecerlo en ancho: 100%, pero tengo curiosidad por saber por qué sucede esto. ¿No se supone que 100vw es "el 100% del ancho de la ventana gráfica"?

rdoyle720
fuente
Evite el desbordamiento oculto en html y body. No es una buena solución si desea usar position sticky en cualquiera de sus elementos secundarios ... ¡¡¡max-width parece ser una buena manera !!!
NeueDeutsche

Respuestas:

148

Como ya se explicó en wf4, el desplazamiento horizontal está presente debido al desplazamiento vertical. que puedes resolver dando max-width: 100%.

.box {
    width: 100vw;
    height: 100vh;
    max-width:100%;  /* added */
}

Violín de trabajo

SR verde
fuente
3
Gracias, esto funciona bien para solucionar el problema, pero sigo pensando que es un comportamiento predeterminado poco intuitivo.
phocks
2
Acerca de no ser intuitivo: según caniuse.com, esto es un error de navegador. caniuse.com/#feat=viewport-units -> Problema conocido 8: actualmente todos los navegadores, excepto Firefox, consideran incorrectamente que 100vw es el ancho de página completo, incluida la barra de desplazamiento vertical, que puede causar una barra de desplazamiento horizontal cuando se establece overflow: auto .
Jacob van Lingen
46
Si max-width: 100%es el ancho de la ventana gráfica sin barras de desplazamiento, entonces no lo necesitaba 100vwen primer lugar :-) Podría tener uso width: 100%porque el elemento no tiene ningún ancestro posicionado, por lo que su referencia es el cuerpo.
Cápsula
7
¡Esto no resuelve nada! ¡max-width solo funciona porque el elemento es un descendiente directo del cuerpo! En cualquier caso del mundo real en el que usaría 100vw en lugar de 100% (como un elemento dentro de un contenedor), esto no funcionará.
Eliezer Berlin
2
No puedo usar el ancho al 100% porque mi div está en un contenedor del que no conozco el ancho o el relleno. Esa es la razón para usar 100vw en lugar del 100%, por lo que esta respuesta no tiene sentido. Y sucede en Mac también si su configuración es mostrar siempre barras de desplazamiento, aunque no haya barra de desplazamiento.
Curtis
37

Las barras de desplazamiento se incluirán en el, vwpor lo que se agregará el desplazamiento horizontal para permitirle ver debajo del desplazamiento vertical.

Cuando solo tienes 1 caja, es 100% de ancho x 100% de alto. Una vez que agrega 2, su 100% de ancho x 200% de alto, por lo tanto, activa la barra de desplazamiento vertical. A medida que se activa la barra de desplazamiento vertical, se activa la barra de desplazamiento horizontal.

Podrías agregar overflow-x:hiddenabody

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/

wf4
fuente
1
Hacer esto hace que el contenido aparezca debajo de la barra de desplazamiento. jsfiddle.net/NBzVV/1 Para que esta sea una solución adecuada, necesitará agregar el relleno correcto.
James Donnelly
1
Sí, bien visto. Añadiendo max-width:100%al .boxevitará.
WF4
4
"por lo que se agregará el desplazamiento horizontal para permitirle ver debajo del desplazamiento vertical" <- esta oración ayudó a mi cerebro a dar sentido visual a lo que realmente estaba sucediendo. +1
Ivan Durst
Solo una nota sobre overflowincluso si lo agrega a xninguna de las postition: stickycosas funcionará.
T.Chmelevskij
8

Tuve un problema similar y se me ocurrió la siguiente solución usando variables JS y CSS.

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 es un valor de respaldo.

Stepan Shatkovski
fuente
Me gusta esto. bastante elegante
andrevenancio
Esto es perfecto porque luego está disponible a nivel mundial. Gracias.
fvaldez421
2

Actualización: a partir de la versión 66 de Chrome, ya no puedo reproducir el comportamiento informado por la pregunta. Parece que no se necesita ninguna solución alternativa.


Respuesta original

Esto es en realidad un error como se informa en esta respuesta y los comentarios anteriores.

Si bien la solución alternativa en la respuesta aceptada (agregar .box {max-width: 100%;}) generalmente funciona, me parece digno de mención que actualmente no funciona display:table(probado en Chrome). En ese caso, la única solución que encontré es usar width:100%en su lugar.

Cornflex
fuente
Uhm, ¿cambió la respuesta aceptada? Sugieres lo mismo que la respuesta aceptada. Es por eso que las respuestas deben estar completas por sí mismas.
Kissaki
La respuesta aceptada propone agregar max-width: 100%. Propuse cambiar width: 100vwa width: 100%. Actualicé mi respuesta para que sea autónoma.
Cornflex
Hay otros navegadores además de Chrome, y algunos tratan la barra de desplazamiento de manera diferente.
LocalPCGuy
1

para deshacerme del ancho de la barra de desplazamiento incluido en vw tuve que hacer esto:

html, body {
    overflow-x: hidden;
    height: 100vh;
}
manuel-84
fuente
1
*,
html,
body {
  margin: 0;
  padding: 0;
  overflow: hidden;/*add This*/ 
}
/*and enjoy ^_^ */
usuario13149444
fuente
5
Ocultar un problema no lo resuelve. Si bien su enfoque elimina el desbordamiento, simplemente lo oculta. Esto puede causar problemas cuando el contenido debe mostrarse en el exterior (por cualquier motivo)
Daniel Steiner
2
¡Hola, usuario 13149444! Las respuestas de solo código pueden resolver el problema, pero son mucho más útiles si explica cómo lo resuelven. La comunidad requiere tanto la teoría como el código para comprender completamente su respuesta.
RBT