Como um elemento html pode preencher 100% da altura restante da tela, usando apenas css?

118

Eu tenho um elemento de cabeçalho e um elemento de conteúdo:

#header
#content

Quero que o cabeçalho tenha altura fixa e o conteúdo preencha toda a altura restante disponível na tela, com overflow-y: scroll;.

Isso é possível sem Javascript?

atormentar
fonte

Respostas:

83

O truque para isso é especificar 100% de altura nos elementos html e body. Alguns navegadores procuram os elementos pais (html, corpo) para calcular a altura.

<html>
    <body>
        <div id="Header">
        </div>
        <div id="Content">
        </div>
    </body>
</html>

html, body
{
    height: 100%;
}
#Header
{
    width: 960px;
    height: 150px;
}
#Content
{
    height: 100%;
    width: 960px;
}
BentOnCoding
fonte
1
Tentei todas as soluções, mas apenas isso resolveu meu problema.
Alex
1
@Alex se isso funcionar para todos os navegadores que você está direcionando, vá em frente e implemente-o. Os requisitos de cada pessoa são diferentes.
BentOnCoding
321

esqueça todas as respostas, esta linha de CSS funcionou para mim em 2 segundos:

height:100vh;

1vh = 1% da altura da tela do navegador

fonte

Para escalonamento de layout responsivo, você pode usar:

min-height: 100vh

[atualização de novembro de 2018] Conforme mencionado nos comentários, usar a altura mínima pode evitar problemas em designs reativos

[atualização de abril de 2018] Conforme mencionado nos comentários, em 2011, quando a pergunta foi feita, nem todos os navegadores suportavam as unidades de janela de visualização. As outras respostas foram as soluções da época - vmaxainda não é compatível com o IE, então essa pode não ser a melhor solução para todos ainda.

Sebastien H.
fonte
9
Esta é a resposta mais simples, pois você não precisa definir a altura de todos os elementos pais para 100%. Aqui está o suporte atual para vh - caniuse.com/#feat=viewport-units - iOS aparentemente pode precisar de uma solução alternativa, pois "vh no iOS é relatado para incluir a altura da barra de ferramentas inferior no cálculo da altura".
Brian Burns de
2
WOW, bom achado! Veja todas essas pessoas com respostas complicadas demais.
NoName
8
Quando a pergunta foi feita em 2011, nenhum dos principais navegadores suportava unidades de janela de visualização. Essas "respostas complicadas demais" eram as únicas opções naquela época.
JJJ
6
Uma pequena sugestão de que a min-height: 100vhseria muito melhor. Também seria escalonado para designs responsivos.
Wiggy A.
3
Isso não responde à pergunta feita, pois ocuparia 100% da janela de visualização. Ele não quer isso porque seu cabeçalho ocupará x% da janela de visualização, já que as outras respostas estão corretas.
4cody
35

Na verdade, a melhor abordagem é esta:

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

Isso resolve tudo para mim e me ajuda a controlar meu rodapé e pode ter o rodapé fixo, não importa se a página está sendo rolada para baixo.

Solução Técnica - EDITADA

Historicamente, 'altura' é algo complicado de se moldar, em comparação com 'largura', a mais fácil. Já que o css foca <body>para que o estilo funcione. O código acima - demos <html>e <body>uma altura. É aqui que a mágica entra em cena - uma vez que temos 'altura mínima' na mesa de jogo, estamos dizendo ao navegador que <body>é superior <html>porque <body>mantém a altura mínima. Este por sua vez, permite <body>anular <html>porque <html>já tinha altura anterior. Em outras palavras, estamos enganando o navegador para "bater" <html>fora da mesa, para que possamos estilizar de forma independente.

Faron
fonte
1
Oh meu Deus é um milagre!
Geoff
Como um milagre, funciona! Mas, por favor: por que min-heighte height?
Joy
1
@ShaojiangCai - Historicamente, 'altura' é uma coisa complicada de se moldar, em comparação com 'largura', a mais fácil. Já que o css foca <body>para que o estilo funcione. Este código: demos <html>e <body>uma altura. É aqui que a mágica entra em cena - uma vez que temos 'altura mínima' na mesa de jogo, estamos dizendo ao servidor que <body>é superior <html>porque <body>mantém a altura mínima. Este por sua vez, permite <body>anular <html>porque <html>já tinha altura anterior. Em outras palavras, estamos enganando o servidor para "bater" <html>fora da mesa, para que possamos estilizar de forma independente.
Faron
2
@Faron Parece que 'navegador' seria uma escolha de palavra melhor aqui em vez de 'servidor'. ;)
LETs,
@EunLeem ... Eu concordo com você sobre como eu poderia ter escolhido o texto adequado para tratar disso. Obrigado pela dica "cotovelo". Atualizei minha resposta em conformidade.
Faron,
14

Você pode usar vh na propriedade min-height.

min-height: 100vh;

Você pode fazer o seguinte, dependendo de como você está usando as margens ...

min-height: calc(100vh - 10px) //Considering you're using some 10px margin top on an outside element
Almeida Cavalcante
fonte
10

A solução aceita realmente não funcionará. Você notará que o conteúdo divserá igual à altura de seu pai body,. Portanto, definir a bodyaltura 100%como igual à altura da janela do navegador. Digamos que a janela do navegador tenha a 768pxaltura, ao definir a divaltura do conteúdo para 100%, a divaltura de será 768px. Assim, você terminará com o div de cabeçalho 150pxe o div de conteúdo 768px. No final, você terá conteúdo 150pxabaixo da parte inferior da página. Para outra solução, verifique este link.

dykstrad
fonte
8

Com HTML5, você pode fazer isso:

CSS:

body, html{ width:100%; height:100%; padding: 0; margin: 0;}
header{ width:100%; height: 70px; }
section{ width: 100%; height: calc(100% - 70px);}

HTML:

<header>blabablalba </header>
<section> Content </section>
Miguel
fonte
Cuidado ao usar cálculo na altura percentual. O Firefox não funcionará corretamente a menos que todos os pais tenham uma altura definida.
TomDK
4

Para mim, o próximo funcionou bem:

Eu envolvi o cabeçalho e o conteúdo em um div

<div class="main-wrapper">
    <div class="header">

    </div>
    <div class="content">

    </div>
</div>

Usei essa referência para preencher a altura com flexbox. O CSS funciona assim:

.main-wrapper {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
}
.header {
    flex: 1;
}
.content {
    flex: 1;
}

Para obter mais informações sobre a técnica flexbox, visite a referência

hasher
fonte
1

Você também pode definir o pai como display: inline. Vejo http://codepen.io/tommymarshall/pen/cECyH

Certifique-se de ter a altura do html e do corpo configurada para 100% também.

Tommymarshall
fonte
Respostas apenas com links são desencorajadas. Tente resumir o conteúdo do link em sua resposta
Usuário que não é um usuário
1

A resposta aceita não funciona. E a resposta com maior votação não responde à pergunta real. Com um cabeçalho de altura de pixel fixa e um preenchimento na exibição restante do navegador, role para owerflow. Aqui está uma solução que realmente funciona, usando posicionamento absoluto. Também suponho que a altura do cabeçalho seja conhecida, pelo som de "cabeçalho fixo" na questão. Eu uso 150px como exemplo aqui:

HTML:

<html>
    <body>
        <div id="Header">
        </div>
        <div id="Content">      
        </div>
    </body>
</html>

CSS: (adicionando cor de fundo apenas para efeito visual)

#Header
{
    height: 150px;
    width: 100%;
    background-color: #ddd;
}
#Content
{
   position: absolute;
   width: 100%;
   top: 150px;
   bottom: 0;
   background-color: #aaa;
   overflow-y: scroll;
}

Para uma visão mais detalhada de como isso funciona, com conteúdo real dentro do #Content, dê uma olhada neste jsfiddle , usando linhas e colunas de bootstrap.

jumps4fun
fonte
"cabeçalho de altura fixa de pixel" -> isso exatamente! A bottompropriedade certificou-se de que o #Contentpermanece preso no final da página. Agradeço por ter dispensado um tempo para explicar isso.
Armfoot
1
E estou feliz que ajudou alguém;)
jumps4fun
1

Neste caso, quero que meu div de conteúdo principal tenha altura líquida para que a página inteira ocupe 100% da altura do navegador.

height: 100vh;

Fezal halai
fonte
1

Deixe-me adicionar meus 5 centavos aqui e oferecer uma solução clássica:

html {height:100%;}
body {height:100%; margin:0;}
#idOuter {position:relative; width:100%; height:100%;}
#idHeader {position:absolute; left:0; right:0; border:solid 3px red;}
#idContent {position:absolute; overflow-y:scroll; left:0; right:0; border:solid 3px green;}
<div id="idOuter">
  <div id="idHeader" style="height:30px; top:0;">Header section</div>
  <div id="idContent" style="top:36px; bottom:0;">Content section</div>
</div>

Isso funcionará em todos os navegadores, sem script, sem flex. Abra o snippet no modo de página inteira e redimensione o navegador: as proporções desejadas são preservadas mesmo no modo de tela inteira.

Nota:

  • Elementos com cores de fundo diferentes podem cobrir uns aos outros. Aqui, usei borda sólida para garantir que os elementos sejam colocados corretamente.
  • idHeader.heighte idContent.topsão ajustados para incluir a borda e devem ter o mesmo valor se a borda não for usada. Caso contrário, os elementos sairão da janela de visualização, já que a largura calculada não inclui borda, margem e / ou preenchimento.
  • left:0; right:0;pode ser substituído pelo width:100%mesmo motivo, se nenhuma borda for usada.
  • O teste em página separada (não como um snippet) não requer nenhum ajuste de html / corpo.
  • No IE6 e em versões anteriores, devemos adicionar padding-tope / ou padding-bottomatributos ao #idOuterelemento.

Para completar minha resposta, aqui está o layout do rodapé:

html {height:100%;}
body {height:100%; margin:0;}
#idOuter {position:relative; width:100%; height:100%;}
#idContent {position:absolute; overflow-y:scroll; left:0; right:0; border:solid 3px green;}
#idFooter {position:absolute; left:0; right:0; border:solid 3px blue;}
<div id="idOuter">
  <div id="idContent" style="bottom:36px; top:0;">Content section</div>
  <div id="idFooter" style="height:30px; bottom:0;">Footer section</div>
</div>

E aqui está o layout com cabeçalho e rodapé:

html {height:100%;}
body {height:100%; margin:0;}
#idOuter {position:relative; width:100%; height:100%;}
#idHeader {position:absolute; left:0; right:0; border:solid 3px red;}
#idContent {position:absolute; overflow-y:scroll; left:0; right:0; border:solid 3px green;}
#idFooter {position:absolute; left:0; right:0; border:solid 3px blue;}
<div id="idOuter">
  <div id="idHeader" style="height:30px; top:0;">Header section</div>
  <div id="idContent" style="top:36px; bottom:36px;">Content section</div>
  <div id="idFooter" style="height:30px; bottom:0;">Footer section</div>
</div>

Dmitry Babich
fonte
0

A menos que você precise oferecer suporte ao IE 9 e inferior, eu usaria o flexbox

body { display: flex; flex-direction: column; }
.header { height: 70px; }
.content { flex: 1 1 0 }

Você também precisa obter o corpo para preencher a página inteira

body, html{ width:100%; height:100%; padding: 0; margin: 0;}
James Lambert
fonte
0
#Header
{
width: 960px;
height: 150px;
}

#Content
{
min-height:100vh;
height: 100%;
width: 960px;
}
Jazib Khan
fonte
-1

A melhor solução que encontrei até agora é definir um elemento de rodapé na parte inferior da página e, em seguida, avaliar a diferença entre o deslocamento do rodapé e o elemento que precisamos expandir. por exemplo

O arquivo html

<div id="contents"></div>
<div id="footer"></div>

O arquivo css

#footer {
    position: fixed;
    bottom: 0;
    width: 100%;
}

O arquivo js (usando jquery)

var contents = $('#contents'); 
var footer = $('#footer');
contents.css('height', (footer.offset().top - contents.offset().top) + 'px');

Você também pode querer atualizar a altura do elemento de conteúdo em cada redimensionamento da janela, então ...

$(window).on('resize', function() {
  contents.css('height', (footer.offset().top -contents.offset().top) + 'px');
});
Αλέκος
fonte
-1

Muito simples:

#content {
    max-height: 100%;
}
Masood
fonte
-3

Você já tentou algo assim?

CSS:

.content {
    height: 100%;
    display: block;
}

HTML:

<div class=".content">
<!-- Content goes here -->
</div>
Rahul Choudhary
fonte