ti-enxame.com

Obtenha div para ocupar 100% da altura do corpo, menos o cabeçalho e o rodapé com altura fixa

Da minha pesquisa, isso parece ser uma pergunta CSS absolutamente clássica, mas não consigo encontrar uma resposta definitiva - então StackOverflow é.

Como faço para definir um div de conteúdo para ocupar 100% da altura do corpo, menos a altura ocupada por um cabeçalho e rodapé de altura fixa?

<body>
  <header>title etc</header>
  <div id="content">body content</div>
  <footer>copyright etc</footer>
</body>

//CSS
html, body { 
  height: 100%;
}
header { 
  height: 50px;
}
footer { 
  height: 50px;
}
#content { 
  height: 100% of the body height, minus header & footer
}

Eu gostaria de usar CSS puro, e para a resposta ser à prova de balas em todos os navegadores.

72
Richard

esta versão irá funcionar em todos os navegadores mais recentes e ie8 se você tiver o script modernizr (se não apenas alterar header e footer em divs):

violino

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

#wrapper {
  padding: 50px 0;
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
}

#content {
  min-height: 100%;
  background-color: green;
}

header {
  margin-top: -50px;
  height: 50px;
  background-color: red;
}

footer {
  margin-bottom: -50px;
  height: 50px;
  background-color: red;
}

p {
  margin: 0;
  padding: 0 0 1em 0;
}
<div id="wrapper">
  <header>dfs</header>
  <div id="content">
  </div>
  <footer>sdf</footer>
</div>

Rolando com conteúdo: violino

55
Pete

Na medida em que não é uma solução cruzada do navegador, você pode aproveitar o uso de calc(expression) para obter isso.

html, body { 
 height: 100%;
}
header {        
 height: 50px;
 background-color: tomato
}

#content { 
 height: -moz-calc(100% - 100px); /* Firefox */
 height: -webkit-calc(100% - 100px); /* Chrome, Safari */
 height: calc(100% - 100px); /* IE9+ and future browsers */
 background-color: yellow 
}
footer { 
 height: 50px;
 background-color: grey;
}

exemplo no JsFiddle

Se você quiser saber mais sobre calc(expression) é melhor você visitar this site.

37
agriboz

Isso ainda surgiu como o principal resultado do Google quando eu estava tentando encontrar uma resposta para essa pergunta. Não tive que suportar navegadores mais antigos no meu projeto e sinto que encontrei uma solução melhor e mais simples em flex-box . O snippet de CSS abaixo é tudo o que é necessário.

Também mostrei como tornar o conteúdo principal rolável se a altura da tela for muito pequena.

html,
body {
  height: 100%;
}
body {
  display: flex;
  flex-direction: column;
}
header {
  min-height: 60px;
}
main {
  flex-grow: 1;
  overflow: auto;
}
footer {
  min-height: 30px;
}
<body style="margin: 0px; font-family: Helvetica; font-size: 18px;">
  <header style="background-color: lightsteelblue; padding: 2px;">Hello</header>
  <main style="overflow: auto; background-color: lightgrey; padding: 2px;">
    <article style="height: 400px;">
      Goodbye
    </article>
  </main>
  <footer style="background-color: lightsteelblue; padding: 2px;">I don't know why you say, "Goodbye"; I say, "Hello."</footer>
</body>
19
Matt L

A maneira nova e moderna de fazer isso é calcular a altura vertical subtraindo a altura do cabeçalho e do rodapé da altura vertical da viewport.

//CSS
header { 
  height: 50px;
}
footer { 
  height: 50px;
}
#content { 
  height: calc(100vh - 50px - 50px);
}
12
Eric Warnke

Tentando calcular o cabeçalho e rodapé é ruim :( Um projeto deve ser simples, auto-explicativo. Simples fácil. Cálculos são apenas ... não é fácil. Não é fácil para o ser humano e um pouco difícil em máquinas.

O que você está procurando é um subconjunto do design do Santo Graal .

Aqui é uma implementação usando o display flex. Inclui barras laterais além do rodapé e cabeçalho. Desfrutar:

<!DOCTYPE html>
<html style="height: 100%">
  <head>
    <meta charset=utf-8 />
    <title>Holy Grail</title>
    <!-- Reset browser defaults -->
    <link rel="stylesheet" href="reset.css">
  </head>
  <body style="display: flex; height: 100%; flex-direction: column">
    <div>HEADER<br/>------------
    </div>
    <!-- No need for 'flex-direction: row' because it's the default value -->
    <div style="display: flex; flex: 1">
      <div>NAV|</div>
      <div style="flex: 1; overflow: auto">
        CONTENT - START<br/>
        <script>
        for (var i=0 ; i<1000 ; ++i) {
          document.write(" Very long content!");
        }
        </script>
        <br/>CONTENT - END
      </div>
      <div>|SIDE</div>
    </div>
    <div>------------<br/>FOOTER</div>
  </body>
</html>
1
AlikElzin-kilaka

Aqui está uma solução que não usa margens negativas ou calc. Execute o trecho abaixo para ver o resultado final.

Explicação

Damos ao cabeçalho e ao rodapé uma altura fixa de 30px e os posicionamos absolutamente na parte superior e inferior, respectivamente. Para evitar que o conteúdo caia por baixo, usamos duas classes: below-header e above-footer para preencher o div acima e abaixo com 30px.

Todo o conteúdo é empacotado em um position: relative div para que o cabeçalho e o rodapé fiquem na parte superior/inferior do conteúdo e não na janela.

Usamos as classes fit-to-parent e min-fit-to-parent para fazer o conteúdo preencher a página. Isso nos dá um rodapé fixo que é pelo menos tão baixo quanto a janela, mas oculto se o conteúdo for maior que a janela.

Dentro do cabeçalho e rodapé, usamos os estilos display: table e display: table-cell para dar ao cabeçalho e ao rodapé um preenchimento vertical sem interromper a qualidade da página. (Dar a eles preenchimento real pode fazer com que a altura total da página seja maior que 100%, o que faz com que uma barra de rolagem apareça quando não é realmente necessária.)

.fit-parent {
    height: 100%;
    margin: 0;
    padding: 0;
}
.min-fit-parent {
    min-height: 100%;
    margin: 0;
    padding: 0;
}
.below-header {
    padding-top: 30px;
}
.above-footer {
    padding-bottom: 30px;
}
.header {
    position: absolute;
    top: 0;
    height: 30px;
    width: 100%;
}
.footer {
    position: absolute;
    bottom: 0;
    height: 30px;
    width: 100%;
}

/* helper classes */

.padding-lr-small {
    padding: 0 5px;
}
.relative {
    position: relative;
}
.auto-scroll {
  overflow: auto;
}
/* these two classes work together to create vertical centering */
.valign-outer {
    display: table;
}
.valign-inner {
    display: table-cell;
    vertical-align: middle;
}
<html class='fit-parent'>
  <body class='fit-parent'>
<div class='min-fit-parent auto-scroll relative' style='background-color: lightblue'>
<div class='header valign-outer' style='background-color: black; color: white;'>
        <div class='valign-inner padding-lr-small'>
            My webpage
        </div>
    </div>
    <div class='fit-parent above-footer below-header'>
        <div class='fit-parent' id='main-inner'>
          Lorem ipsum doloris finding dory Lorem ipsum doloris finding
          dory Lorem ipsum doloris finding dory Lorem ipsum doloris
          finding dory Lorem ipsum doloris finding dory Lorem ipsum
          doloris finding dory Lorem ipsum doloris finding dory Lorem
          ipsum doloris finding dory Lorem ipsum doloris finding dory
          Lorem ipsum doloris finding dory Lorem ipsum doloris finding
          dory Lorem ipsum doloris finding dory Lorem ipsum doloris
          finding dory Lorem ipsum doloris finding dory Lorem ipsum
          doloris finding dory Lorem ipsum doloris finding dory Lorem
          ipsum doloris finding dory Lorem ipsum doloris finding dory
          Lorem ipsum doloris finding dory Lorem ipsum doloris finding
          dory Lorem ipsum doloris finding dory Lorem ipsum doloris
          finding dory Lorem ipsum doloris finding dory Lorem ipsum
          doloris finding dory Lorem ipsum doloris finding dory Lorem
          ipsum doloris finding dory Lorem ipsum doloris finding dory
          Lorem ipsum doloris finding dory Lorem ipsum doloris finding
          dory Lorem ipsum doloris finding dory Lorem ipsum doloris
          finding dory Lorem ipsum doloris finding dory Lorem ipsum
          doloris finding dory Lorem ipsum doloris finding dory Lorem
          ipsum doloris finding dory Lorem ipsum doloris finding dory
          Lorem ipsum doloris finding dory Lorem ipsum doloris finding
          dory Lorem ipsum doloris finding dory Lorem ipsum doloris
          finding dory Lorem ipsum doloris finding dory Lorem ipsum
          doloris finding dory Lorem ipsum doloris finding dory Lorem
          ipsum doloris finding dory Lorem ipsum doloris finding dory
          Lorem ipsum doloris finding dory Lorem ipsum doloris finding
          dory Lorem ipsum doloris finding dory Lorem ipsum doloris
          finding dory Lorem ipsum doloris finding dory Lorem ipsum
          doloris finding dory Lorem ipsum doloris finding dory Lorem
          ipsum doloris finding dory Lorem ipsum doloris finding dory
          Lorem ipsum doloris finding dory Lorem ipsum doloris finding
          dory Lorem ipsum doloris finding dory Lorem ipsum doloris
          finding dory Lorem ipsum doloris finding dory Lorem ipsum
          doloris finding dory Lorem ipsum doloris finding dory Lorem
          ipsum doloris finding dory Lorem ipsum doloris finding dory
        </div>
    </div>
    <div class='footer valign-outer' style='background-color: white'>
        <div class='valign-inner padding-lr-small'>
            &copy; 2005 Old Web Design
        </div>
    </div>
</div>
    </body>
  </html>
0
Chris Middleton

Esta pergunta foi bem respondida, mas estou tomando a liberdade de adicionar uma solução de javascript. Basta fornecer ao elemento que você deseja 'expandir' o id footerspacerdiv, e esse snippet de javascript expandirá esse div até que a página ocupe toda a altura da janela do navegador.

Ele funciona com base na observação de que, quando uma página é menor que a altura total da janela do navegador, document.body.scrollHeight é igual a document.body.clientHeight. O loop while aumenta a altura de footerspacerdiv até document.body.scrollHeight ser maior que document.body.clientHeight. Neste ponto, footerspacerdiv terá 1 pixel de altura e o navegador mostrará uma barra de rolagem vertical. Portanto, a última linha do script reduz a altura de footerspacerdiv em um pixel para tornar a altura da página exatamente a altura da janela do navegador.

Colocando footerspacerdiv logo acima do 'rodapé' da página, esse script pode ser usado para 'Empurrar o rodapé para baixo' para a parte inferior da página, para que em páginas curtas, o rodapé fique nivelado com a parte inferior da janela do navegador.

<script>    
//expand footerspacer div so that footer goes to bottom of page on short pages        
  var objSpacerDiv=document.getElementById('footerspacer');          
  var bresize=0;   

  while(document.body.scrollHeight<=document.body.clientHeight) {
    objSpacerDiv.style.height=(objSpacerDiv.clientHeight+1)+"px";
    bresize=1;
  }             
  if(bresize) { objSpacerDiv.style.height=(objSpacerDiv.clientHeight-1)+"px"; }               
 </script>
0
mti2935