Artigo original: HTML vs Body: How to Set Width and Height for Full Page Size

O CSS é difícil, mas deixa passar muita coisa. É por isso que ele nos permite lançar estilos do jeito que quisermos em nossa página.

A página ainda carrega sem quebrar.

Quando falamos de altura e largura da página, você sabe o que você deve configurar no elemento HTML? E no elemento body?

Você simplesmente joga os estilos nos elementos e espera que dê certo?

Se faz isso, saiba que não está sozinho.

As respostas para essas perguntas não são intuitivas.

Eu sou 100% culpado de aplicar estilos aos dois elementos no passado sem considerar exatamente qual propriedade deveria ser aplicada a qual elemento. 🤦‍♂️

Não é incomum ver propriedades do CSS aplicadas tanto aos elemento HTML quanto ao elemento body dessa forma:

html, body {
     min-height: 100%;
}

Isso importa?

Sim, importa.

A definição de estilo acima cria um problema:

Definir min-height como 100% nos dois elementos não permite que o elemento body preencha a página como você deveria esperar. Se você verificar os valores de estilo calculados nas ferramentas de desenvolvedor, o elemento body tem uma altura de zero.

Enquanto isso, o elemento HTML tem uma altura igual à parte visível da página no navegador.

Veja a imagem abaixo, retirada das Ferramentas do Desenvolvedor do Chrome:

empty_body
O elemento body tem uma margem padrão de 8px, indicada pela barra na parte superior. O valor da altura é 0.

Por que isso acontece?

Usar uma porcentagem como o valor para o tamanho requer que o elemento faça referência a um elemento pai para ter a base dessa porcentagem.

O elemento HTML faz referência à viewport, que tem um valor de altura igual à altura visível da viewport. Porém, definimos apenas uma altura mínima (min-height) no elemento HTML... NÃO um valor para a propriedade altura (height).

Assim, o elemento body não tem o valor de altura do elemento pai para fazer referência quando precisa decidir a que os 100% estão se referindo.

O problema também pode estar oculto

Se você começou sem conteúdo suficiente para preencher o body da página, você pode não ter notado esse problema.

Para tornar tudo mais difícil de perceber, se você definiu uma background-color nos dois elementos ou apenas em um deles, a viewport está totalmente daquela cor. Isso dá a impressão de que o elemento body tem a altura da viewport.

Mas não tem. Ele ainda tem altura zero.

A imagem acima é retirada de uma página com o seguinte CSS:

html, body {
    min-height: 100%;
}
body { background-color: dodgerblue; }

Herança inversa?

É uma virada de jogo estranha, mas o elemento HTML recebe a background-color do elemento body se você não definir uma background-color separada para o elemento html.

Como, então, definir uma altura ideal para uma página inteira responsiva?

Por anos, a resposta foi a seguinte:

html {
    height: 100%;
}
body {
    min-height: 100%;
}

Isso permite que o elemento HTML faça referência à viewport pai e tenha um valor de altura (height) igual a 100% do valor da viewport.

Como o elemento HTML recebendo um valor para height, o valor de min-height atribuído ao elemento body dá a ele uma altura inicial que corresponde ao elemento HTML.

Isso também permite que o body seja até maior se o conteúdo tiver uma altura maior do que a da página visível.

O único efeito colateral é o fato de que o elemento HTML não consegue crescer para além da viewport visível. No entanto, permitir que o elemento body seja maior que o elemento HTML vem sendo considerado algo aceitável.

A solução moderna é mais simples

body { min-height: 100vh; }

Este exemplo usa a unidade vh (a altura da viewport) para permitir que o body defina um valor de altura mínima com base na altura total da viewport.

Da mesma forma que ocorre com o background-color discutido anteriormente, se não definirmos um valor de altura (height) para o elemento HTML, ele assumirá o mesmo valor de height dado ao elemento body.

Portanto, essa solução evita o overflow do elemento HTML presente na situação anterior. Os dois elementos crescem junto com seu conteúdo!

O uso das unidades vh causou alguns problemas nos dispositivos móveis no passado, mas parece que o Chrome e o Safari agora estão consistentes com relação às unidades da viewport (texto em inglês).

A altura da página pode gerar uma barra de rolagem horizontal

Quê? Como assim?

Não seria, na verdade, uma "largura da página"?

Não.

Em outra série estranha de eventos, sua altura da página pode ativar uma barra de rolagem horizontal no seu navegador.

Quando o conteúdo da sua página ficar maior do que a altura da viewport, a barra de rolagem vertical à direita é ativada. Isso pode fazer com que sua página também tenha, instantaneamente, uma barra de rolagem horizontal.

Como consertar isso?

Talvez você durma melhor sabendo que isso começa com uma definição da largura da página.

Esse problema surge quando qualquer elemento - não apenas os elementos HTML e body - estiverem definidos com 100vw (unidades de largura da viewport).

As unidades da viewport não respondem pelos aproximadamente 10 pixels que a barra de rolagem vertical toma para si.

Assim, quando a barra de rolagem vertical é ativada, você também recebe uma barra de rolagem horizontal.

Como definir a largura total da página

E que tal, simplesmente, não fazer isso?

Não definir uma largura (width) nos elementos HTML e body deixará o padrão como sendo a largura total da tela. Se você definir um valor de width que não seja auto, considere utilizar uma redefinição do CSS primeiro.

Lembre-se: por padrão, o elemento body tem 8px de margem em todos os lados.

Uma redefinição do CSS remove isso. Do contrário, definir width como 100% antes de remover as margens fará com que o elemento body tenha um overflow. Esta é a redefinição de CSS que eu uso:

* { 
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

Como definir uma largura de sua preferência

Embora nem sempre seja necessário definir uma largura (width), isso é o que eu normalmente faço.

Pode ser apenas questão de hábito.

Se você definir a largura como 100% no elemento body, terá uma largura inteira de página. Isso é essencialmente equivalente a não definir um valor para width e permitir que seja o padrão.

Se quiser usar o elemento body como um contêiner menor e deixar que o elemento HTML preencha a página, você pode definir um valor máximo de largura (max-width) para o body.

Aqui vemos um exemplo:

html { background-color: #000; } 
body {
    min-height: 100vh;
    max-width: 400px;
    background-color: papayawhip; 
    margin: 0 auto;
}

Conclusão

Se nenhum valor de height tiver sido fornecido para o elemento HTML, definir a altura (height) e/ou a altura mínima (min-height) do elemento body como 100% resultará em nada de altura (antes de você adicionar conteúdo).

Porém, se nenhum valor de width tiver sido fornecido para o elemento HTML, definir a largura (width) do elemento body como 100% resulta em uma largura total da página.

Isso pode ser contraintuitivo e confuso.

Para ter uma altura total de página responsiva, defina min-height no elemento body como 100vh.

Se você definir uma largura de página, prefira 100% a 100vw para evitar a surpresa com as barras de rolagem horizontais.

Deixo aqui um tutorial do meu canal do YouTube demostrando as definições para altura e largura do CSS para uma página HTML com tamanho total de tela e que cresce juntamente ao conteúdo que ela tem:

Você tem uma forma diferente de definir a altura e a largura do CSS de sua preferência?

Conte para a gente qual é o seu método!