100vw causando estouro horizontal, mas somente se mais de um?

101

Diga que você tem isso:

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

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

Você verá algo que preenche a tela, sem barras de rolagem. Mas adicione outro:

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

Você obtém não apenas barras de rolagem verticais (esperado), mas uma leve rolagem horizontal.

Sei que você pode omitir a largura ou defini-la como largura: 100%, mas estou curioso para saber por que isso está acontecendo. 100vw não deveria ser "100% da largura da janela de visualização"?

rdoyle720
fonte
evite overflow oculto em html e body não é uma boa solução se você quiser usar position sticky em qualquer um de seus elementos filhos ... max-width parece ser um bom caminho !!!
NeueDeutsche

Respostas:

156

Como já explicado por wf4, a rolagem horizontal está presente por causa da rolagem vertical. que você pode resolver dando max-width: 100%.

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

Trabalho violino

Senhor Verde
fonte
3
Obrigado, isso funciona bem para corrigir o problema, mas ainda acho que é um comportamento padrão pouco intuitivo.
phocks
2
Sobre não ser intuitivo: de acordo com caniuse.com, este é um navegadorbug. caniuse.com/#feat=viewport-units -> Problema conhecido 8: atualmente, todos os navegadores, exceto o Firefox, consideram incorretamente 100vw como a largura da página inteira, incluindo a barra de rolagem vertical, o que pode causar uma barra de rolagem horizontal quando estouro: automático está definido .
Jacob van Lingen
48
Se max-width: 100%for a largura da janela de visualização sem barras de rolagem, então você não precisava 100vwem primeiro lugar :-) Você poderia apenas usar width: 100%porque o elemento não possui nenhum ancestral posicionado, então sua referência é o corpo.
Cápsula de
8
Isso não resolve nada! max-width só funciona porque o elemento é um descendente direto do corpo! Em qualquer caso do mundo real em que você usaria 100vw em vez de 100% (como um elemento dentro de um contêiner), isso não funcionará.
Eliezer Berlin
2
Não posso usar largura 100% porque meu div está em um contêiner que não sei a largura ou o preenchimento. Essa é a razão para usar 100vw em vez de 100%, então essa resposta é inútil. E isso acontece no Mac também se sua configuração é sempre mostrar barras de rolagem, mesmo que não haja barra de rolagem.
Curtis
38

barras de rolagem serão incluídas no vwpara que a rolagem horizontal seja adicionada para permitir que você veja abaixo da rolagem vertical.

Quando você tem apenas 1 caixa, ela tem 100% de largura x 100% de altura. Depois de adicionar 2, é 100% largo x 200% alto, acionando a barra de rolagem vertical. Conforme a barra de rolagem vertical é acionada, isso aciona a barra de rolagem horizontal.

Você pode adicionar 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
fonte
1
Isso faz com que o conteúdo apareça abaixo da barra de rolagem. jsfiddle.net/NBzVV/1 Para que esta seja uma solução alternativa adequada, você precisa adicionar o preenchimento correto.
James Donnelly,
1
Sim, bem localizado. Adicionar max-width:100%a .boxevitará isso.
wf4
4
"então, a rolagem horizontal será adicionada para permitir que você veja sob a rolagem vertical" <- esta frase ajudou meu cérebro a dar um sentido visual ao que realmente estava acontecendo. +1
Ivan Durst,
Apenas uma observação sobre overflowaté mesmo se você adicioná-lo ao, xnenhuma das postition: stickycoisas funcionará.
T.Chmelevskij
14

Eu tive um problema semelhante e vim com a seguinte solução usando variáveis ​​JS e 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 é um valor substituto.

Stepan Shatkovski
fonte
1
Amo isso. bastante elegante
andrevenancio
Isso é perfeito porque está disponível globalmente. Obrigado.
fvaldez421
Esta é uma ótima técnica, obrigado por compartilhar! Uma pegadinha é que esse script precisa ser executado depois que o dom é carregado para o dimensionamento inicial, então coloque-o no rodapé ou adicione um evento DOMContentLoaded.
escavado em
2

Atualização: a partir da versão 66 do Chrome, não consigo mais reproduzir o comportamento relatado por pergunta. Nenhuma solução alternativa parece ser necessária.


Resposta Original

Na verdade, este é um bug conforme relatado nesta resposta e nos comentários acima.

Embora a solução alternativa na resposta aceita (adição .box {max-width: 100%;}) geralmente funcione, acho digno de nota que ela não funciona atualmente para display:table(testado no Chrome). Nesse caso, a única solução alternativa que encontrei é usar width:100%.

Cornflex
fonte
Uhm, a resposta aceita mudou? Você está sugerindo a mesma coisa que a resposta aceita. É por isso que as respostas devem ser completas por si mesmas.
Kissaki
A resposta aceita propõe adicionar max-width: 100%. Eu propus mudar width: 100vwpara width: 100%. Eu atualizei minha resposta para ser independente.
Cornflex
1
Existem outros navegadores além do Chrome, e alguns lidam com a barra de rolagem de maneira diferente.
LocalPCGuy
0

para me livrar da largura da barra de rolagem incluída no vw, tive que fazer isso:

html, body {
    overflow-x: hidden;
    height: 100vh;
}
manuel-84
fonte
0
*,
html,
body {
  margin: 0;
  padding: 0;
  overflow: hidden;/*add This*/ 
}
/*and enjoy ^_^ */
user13149444
fonte
6
Esconder um problema não o resolve. Embora sua abordagem realmente remova o estouro, ela simplesmente o oculta. Isso pode causar problemas quando o conteúdo deve ser exibido fora (por qualquer motivo)
Daniel Steiner
3
Olá, usuário13149444! Respostas apenas em código podem resolver o problema, mas são muito mais úteis se você explicar como o resolvem. A comunidade requer teoria e também código para entender sua resposta completamente.
RBT