Faça uma div preencher a altura do espaço restante na tela

1910

Estou trabalhando em um aplicativo da web em que desejo que o conteúdo preencha a altura da tela inteira.

A página tem um cabeçalho, que contém um logotipo e informações da conta. Essa pode ser uma altura arbitrária. Quero que a div de conteúdo preencha o restante da página até o final.

Eu tenho um cabeçalho dive um conteúdo div. No momento, estou usando uma tabela para o layout da seguinte forma:

CSS e HTML

#page {
    height: 100%; width: 100%
}

#tdcontent {
    height: 100%;
}

#content {
    overflow: auto; /* or overflow: hidden; */
}
<table id="page">
    <tr>
        <td id="tdheader">
            <div id="header">...</div>
        </td>
    </tr>
    <tr>
        <td id="tdcontent">
            <div id="content">...</div>
        </td>
    </tr>
</table>

Toda a altura da página é preenchida e nenhuma rolagem é necessária.

Para qualquer coisa dentro da div de conteúdo, a configuração top: 0;a colocará logo abaixo do cabeçalho. Às vezes, o conteúdo será uma tabela real, com sua altura definida para 100%. Colocar headerdentro contentnão permitirá que isso funcione.

Existe uma maneira de obter o mesmo efeito sem usar o table?

Atualizar:

Os elementos dentro do conteúdo divtambém terão alturas definidas para porcentagens. Então, algo a 100% dentro do divpreenchê-lo-á até o fundo. Assim como dois elementos a 50%.

Atualização 2:

Por exemplo, se o cabeçalho #contentocupar 20% da altura da tela, uma tabela especificada a 50% dentro ocuparia 40% do espaço da tela. Até agora, envolver a coisa toda em uma tabela é a única coisa que funciona.

Vincent McNabb
fonte
31
Para qualquer pessoa que tropeçar aqui no futuro, é possível obter o layout de tabela desejado na maioria dos navegadores, sem a marcação da tabela, usando display:tablepropriedades e relacionadas, consulte esta resposta para uma pergunta muito semelhante.
AmeliaBR
3
Tentei recriar sua configuração - jsfiddle.net/ceELs - mas não está funcionando, o que sinto falta?
Gill Bates
5
@Senhor. A resposta de estrangeiro é simples e útil, check it out http://stackoverflow.com/a/23323175/188784
Gohan
4
Na verdade, o que você descreve não funciona, mesmo com tabelas: se o conteúdo ocupa mais espaço vertical do que a altura da tela, a célula da tabela e toda a tabela se expandem além da parte inferior da tela. O conteúdo excede o limite: auto não fará aparecer uma barra de rolagem.
Damien
@GillBates funcionará depois que você especificar a altura do elemento pai, veja jsfiddle.net/ceELs/5
Michal Vašut

Respostas:

1113

Atualização de 2015: a abordagem flexbox

Há duas outras respostas mencionando brevemente o flexbox ; no entanto, isso foi há mais de dois anos e eles não fornecem nenhum exemplo. A especificação para o flexbox definitivamente se estabeleceu agora.

Nota: Embora a especificação do CSS Flexible Boxes Layout esteja no estágio Recomendação do Candidato, nem todos os navegadores a implementaram. A implementação do WebKit deve ser prefixada com -webkit-; O Internet Explorer implementa uma versão antiga da especificação, prefixada com -ms-; O Opera 12.10 implementa a versão mais recente da especificação, sem prefixo. Consulte a tabela de compatibilidade em cada propriedade para obter um status de compatibilidade atualizado.

(extraído de https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Flexible_boxes )

Todos os principais navegadores e IE11 + suportam Flexbox. Para o IE 10 ou mais antigo, você pode usar o calço FlexieJS.

Para verificar o suporte atual, você também pode ver aqui: http://caniuse.com/#feat=flexbox

Exemplo de trabalho

Com o flexbox, você pode alternar facilmente entre qualquer uma de suas linhas ou colunas com dimensões fixas, dimensões de tamanho de conteúdo ou dimensões de espaço restante. No meu exemplo, configurei o cabeçalho para ajustar ao conteúdo (conforme a pergunta dos OPs), adicionei um rodapé para mostrar como adicionar uma região de altura fixa e, em seguida, defina a área de conteúdo para preencher o espaço restante.

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

.box {
  display: flex;
  flex-flow: column;
  height: 100%;
}

.box .row {
  border: 1px dotted grey;
}

.box .row.header {
  flex: 0 1 auto;
  /* The above is shorthand for:
  flex-grow: 0,
  flex-shrink: 1,
  flex-basis: auto
  */
}

.box .row.content {
  flex: 1 1 auto;
}

.box .row.footer {
  flex: 0 1 40px;
}
<!-- Obviously, you could use HTML5 tags like `header`, `footer` and `section` -->

<div class="box">
  <div class="row header">
    <p><b>header</b>
      <br />
      <br />(sized to content)</p>
  </div>
  <div class="row content">
    <p>
      <b>content</b>
      (fills remaining space)
    </p>
  </div>
  <div class="row footer">
    <p><b>footer</b> (fixed height)</p>
  </div>
</div>

No CSS acima, a propriedade flex abrevia as propriedades flex-grow , flex-shrink e flex-base para estabelecer a flexibilidade dos itens flex. O Mozilla tem uma boa introdução ao modelo de caixas flexíveis .

Pebbl
fonte
9
Por que o flex: 0 1 30px;atributo box .rowé substituído em todas as div?
precisa
11
Aqui está o suporte ao navegador para flexbox - bom ver tudo que o verde - caniuse.com/#feat=flexbox
Brian Burns
1
O link para o Flexie.js está morto. Aqui o projeto do github github.com/doctyper/flexie
ses3ion
52
Definitivamente, é uma abordagem muito boa e quase funciona;) Há um pequeno problema quando o conteúdo de div.content excede a altura original de flexão. Na implementação atual, o "rodapé" será empurrado para baixo e isso não é o que os desenvolvedores esperam;) Então, eu fiz uma correção muito fácil. jsfiddle.net/przemcio/xLhLuzf9/3 Adicionei flexibilidade adicional no contêiner e na rolagem de estouro.
Przemcio 13/07/2016
12
@przemcio bom ponto, mas eu não acho que ter conteúdo de rolagem é o que cada desenvolvedor espera;) - você só deve precisar adicionar overflow-y: autoa .row.contentconseguir o que você precisa no entanto.
Pebbl
226

Realmente não existe uma maneira sólida e de vários navegadores para fazer isso em CSS. Supondo que seu layout tenha complexidades, você precisa usar JavaScript para definir a altura do elemento. A essência do que você precisa fazer é:

Element Height = Viewport height - element.offset.top - desired bottom margin

Depois de obter esse valor e definir a altura do elemento, você precisa anexar manipuladores de eventos à janela onload e onresize, para poder disparar sua função de redimensionamento.

Além disso, supondo que seu conteúdo possa ser maior que a janela de visualização, você precisará definir overflow-y para rolar.

NICCAI
fonte
2
Era disso que eu suspeitava. No entanto, o aplicativo também funcionará com o Javascript desativado, então acho que continuarei usando a tabela.
Vincent McNabb
6
Vincent, maneira de defender sua posição. Eu estava olhando para fazer exatamente a mesma coisa e parece impossível com css? Não tenho certeza, mas, independentemente disso, nenhuma das outras toneladas de soluções faz o que você descreveu. O javascript é o único que funciona corretamente neste momento.
Travis
5
e se a altura da janela for alterada
Techsin 17/11/2013
4
Quero dizer ... por que não estamos usando o calc em 2013?
21414 kamii
4
altura: calc (100vh - 400px); é um estilo CSS válido que faz exatamente do que trata este post. Todas as outras soluções contam com uma altura fixa dos pais ou uma exibição de bloco.
WilliamX
167

A postagem original é mais de 3 anos atrás. Acho que muitas pessoas que chegam a este post como eu estão procurando uma solução de layout semelhante a um aplicativo, digamos um cabeçalho, rodapé e conteúdo de altura total que ocupam a tela restante. Nesse caso, este post pode ajudar, funciona no IE7 +, etc.

http://blog.stevensanderson.com/2011/10/05/full-height-app-layouts-a-css-trick-to-make-it-easier/

E aqui estão alguns trechos desse post:

@media screen { 
  
  /* start of screen rules. */ 
  
  /* Generic pane rules */
  body { margin: 0 }
  .row, .col { overflow: hidden; position: absolute; }
  .row { left: 0; right: 0; }
  .col { top: 0; bottom: 0; }
  .scroll-x { overflow-x: auto; }
  .scroll-y { overflow-y: auto; }

  .header.row { height: 75px; top: 0; }
  .body.row { top: 75px; bottom: 50px; }
  .footer.row { height: 50px; bottom: 0; }
  
  /* end of screen rules. */ 
}
<div class="header row" style="background:yellow;">
    <h2>My header</h2>
</div> 
<div class="body row scroll-y" style="background:lightblue;">
    <p>The body</p>
</div> 
<div class="footer row" style="background:#e9e9e9;">
    My footer
</div>

h - n
fonte
74
Há apenas um problema com isso: o cabeçalho e o rodapé não são dimensionados automaticamente. Essa é a verdadeira dificuldade, e que é por isso que um "isso não é possível" resposta está atualmente no topo ...
Roman Starkov
Eu precisava de um cabeçalho de 55px e uma div que preencha o restante da altura do documento. esta é a solução!
Matías Cánepa
Você é a bomba, venho tentando há tanto tempo e essa é a única solução que encontrei. Eu precisava que meu elemento nav tivesse 60px de altura na parte superior e o restante abrangesse 100%, isso resolveu.
Adam Waite
Isso funciona bem, exceto que eu estou tendo um pequeno problema - se eu colocar um elemento display: tableno corpo, ele parece transbordar. Fazer isso height: 100%não produz a altura correta.
GStar
4
.colnão é usado, é?
slartidan
143

Em vez de usar tabelas na marcação, você pode usar tabelas CSS.

Marcação

<body>    
    <div>hello </div>
    <div>there</div>
</body>

CSS (relevante)

body
{
    display:table;
    width:100%;
}
div
{
    display:table-row;
}
div+ div
{
    height:100%;  
}

FIDDLE1 e FIDDLE2

Algumas vantagens deste método são:

1) Menos marcação

2) A marcação é mais semântica que as tabelas, porque não se trata de dados tabulares.

3) O suporte ao navegador é muito bom : IE8 +, todos os navegadores e dispositivos móveis modernos ( caniuse )


Apenas para completar, eis os elementos Html equivalentes às propriedades css do modelo de tabela CSS

table    { display: table }
tr       { display: table-row }
thead    { display: table-header-group }
tbody    { display: table-row-group }
tfoot    { display: table-footer-group }
col      { display: table-column }
colgroup { display: table-column-group }
td, th   { display: table-cell }
caption  { display: table-caption } 
Danield
fonte
3
Eu apenas fui apontado para a técnica de tabelas CSS . Acontece que a resposta já estava nesta pergunta respondida. Esta é a melhor solução; limpo, elegante e usando a ferramenta exata da maneira exata a que ela foi projetada. Tabelas CSS
Ian Boyd
O código do violino não corresponde exatamente à resposta aqui. Adicionar html, body { height: 100%, width: 100% }parecia crítico nos meus testes.
mlibby
8
Um recurso irritante das tabelas CSS é exatamente o mesmo que as tabelas normais: se o conteúdo for muito grande, eles expandem a célula para caber. Isso significa que você ainda pode precisar limitar o tamanho (altura máxima) ou definir a altura do código se a página for dinâmica. Eu realmente sinto falta das grades do Silverlight! :(
Gone Coding
3
Você sempre pode adicionar um contêiner absolutamente posicionado dentro do elemento de linha da tabela e definir sua largura e altura para 100%. Lembre-se de definir a posição para relativa no elemento de linha da tabela também.
Mike Mellor 13/05
1
O @MikeMellor não funciona no IE11, uma vez que parece ignorar o relativeposicionamento no table-rowelemento, portanto, leva a altura do ascendente da primeira posição que não é um elemento da tabela.
dwelle
96

Abordagem apenas CSS (se a altura for conhecida / fixa)

Quando você deseja que o elemento do meio se estenda verticalmente por toda a página, é possível usar calc() que é introduzido no CSS3.

Supondo que tenhamos uma altura header e footerelementos fixos e desejemos que a sectiontag use toda a altura vertical disponível ...

Demo

A marcação assumida e seu CSS devem ser

html,
body {
  height: 100%;
}

header {
  height: 100px;
  background: grey;
}

section {
  height: calc(100% - (100px + 150px));
  /* Adding 100px of header and 150px of footer */
  background: tomato;
}

footer {
  height: 150px;
  background-color: blue;
}
<header>100px</header>
<section>Expand me for remaining space</section>
<footer>150px</footer>

Então, aqui, o que estou fazendo é somar a altura dos elementos e deduzir do 100%usocalc() função.

Apenas certifique-se de usar height: 100%;os elementos pai.

Mr. Alien
fonte
13
O OP disse que o cabeçalho poderia ter uma altura arbitrária. Então, se você não sabe a altura de antecedência, você não será capaz de usar calc :(
DanielD
1
@Danield É por isso que eu mencionei altura fixa :)
Sr. Estrangeiro
3
Esta é a solução que funcionou para mim e não exigiu que eu redesenhasse minhas páginas existentes em torno de caixas flexíveis. Se você estiver usando o LESS, ou seja, o Bootstrap, certifique-se de ler o post do coderwall sobre como escapar da função calc () para que o LESS não lide com isso.
precisa saber é o seguinte
1
Op disse: "Esta pode ser uma altura arbitrária". Meios arbitrários decididos pelo projetista, assim fixados. Esta solução é de longe a melhor.
JCK
57

Usava: height: calc(100vh - 110px);

código:

  
.header { height: 60px; top: 0; background-color: green}
.body {
    height: calc(100vh - 110px); /*50+60*/
    background-color: gray;
}
.footer { height: 50px; bottom: 0; }
  
<div class="header">
    <h2>My header</h2>
</div> 
<div class="body">
    <p>The body</p>
</div> 
<div class="footer">
    My footer
</div>

nguyên
fonte
1
Na minha opinião, a solução mais limpa. É melhor do que adicionar javascript, com certeza. (mas a resposta já foi postada em 2015 por outra pessoa)
bvdb
isso parece muito mais limpo.
theprogrammer
44

Uma solução simples, usando o flexbox:

html,
body {
  height: 100%;
}

body {
  display: flex;
  flex-direction: column;
}

.content {
  flex-grow: 1;
}
<body>
  <div>header</div>
  <div class="content"></div>
</body>

Amostra Codepen

Uma solução alternativa, com uma div centralizada na div de conteúdo

zok
fonte
4
Esta é a melhor resposta, com certeza. Funciona como um encanto para home pages herói-img, ou uma combinação do herói-img com a sua barra de navegação
noobcoderiam
jsfiddle.net/31ng75du/5 Testado com Chrome, FF, Edge, Vivaldi
user2360831 04/01
Isso é simples e melhor.
Dev Anand
38

Que tal você simplesmente usar vhque significa view heightem CSS ...

Veja abaixo o snippet de código que criei para você e execute-o:

body {
  padding: 0;
  margin: 0;
}

.full-height {
  width: 100px;
  height: 100vh;
  background: red;
}
<div class="full-height">
</div>

Além disso, veja a imagem abaixo que criei para você:

Faça uma div preencher a altura do espaço restante na tela

Alireza
fonte
10
Isso só é bom se você quiser que uma div abranja toda a altura da janela. Agora coloque um cabeçalho div acima dele com uma altura desconhecida.
LarryBud # 03
@LarryBud você está certo, isso faz com que o div capa, então tudo deveria passa dentro deste div ...
Alireza
34

CSS3 Simple Way

height: calc(100% - 10px); // 10px is height of your first div...

atualmente, todos os principais navegadores são compatíveis; portanto, vá em frente se você não tiver necessidade de oferecer suporte a navegadores antigos.

dev.meghraj
fonte
4
Isso não funciona se você não souber a altura dos outros elementos (por exemplo, se eles contiverem um número variável de elementos filhos).
Ege Ersoz
você também pode usar 100vh, qualquer um que faz isso: não se esqueça de colocar espaços entre os menos e os elementos
htafoya
28

Isso pode ser feito exclusivamente CSSusando vh:

#page {
    display:block; 
    width:100%; 
    height:95vh !important; 
    overflow:hidden;
}

#tdcontent {
    float:left; 
    width:100%; 
    display:block;
}

#content {      
    float:left; 
    width:100%; 
    height:100%; 
    display:block; 
    overflow:scroll;
}

e a HTML

<div id="page">

   <div id="tdcontent"></div>
   <div id="content"></div>

</div>

Eu verifiquei, Ele funciona em todos os principais navegadores: Chrome, IEeFireFox

Ormoz
fonte
2
Uau, nunca ouvi falar vhe vwunidades antes. Mais informações: snook.ca/archives/html_and_css/vm-vh-units
Steve Bennett
Infelizmente, isso não oferece suporte ao IE8 :(
Scott
2
Eu tentei essa abordagem, mas o height: 100%on #contentfez com que sua altura correspondesse à de #pageignorar #tdcontentcompletamente a altura. Com muito conteúdo, a barra de rolagem se estende além da parte inferior da página.
Brandon
28

Nenhuma das soluções postadas funciona quando você precisa da div inferior para rolar quando o conteúdo é muito alto. Aqui está uma solução que funciona nesse caso:

.table {
  display: table;
}

.table-row {
  display: table-row;
}

.table-cell {
  display: table-cell;
}

.container {
  width: 400px;
  height: 300px;
}

.header {
  background: cyan;
}

.body {
  background: yellow;
  height: 100%;
}

.body-content-outer-wrapper {
  height: 100%;
}

.body-content-inner-wrapper {
  height: 100%;
  position: relative;
  overflow: auto;
}

.body-content {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
}
<div class="table container">
  <div class="table-row header">
    <div>This is the header whose height is unknown</div>
    <div>This is the header whose height is unknown</div>
    <div>This is the header whose height is unknown</div>
  </div>
  <div class="table-row body">
    <div class="table-cell body-content-outer-wrapper">
      <div class="body-content-inner-wrapper">
        <div class="body-content">
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
        </div>
      </div>
    </div>
  </div>
</div>

Fonte original: Preenchendo a altura restante de um contêiner durante o processamento de estouro em CSS

Visualização ao vivo do JSFiddle

John Kurlak
fonte
Obrigado!!! Tentei todas as respostas que não são de tabela e não são do tipo flexbox e essa é a única que funcionou 100% corretamente. Uma pergunta: a fonte original possui apenas a body-content-wrapper, e as coisas parecem funcionar muito bem sem o invólucro duplo (sem table-cells). Existe algum problema em fazê-lo dessa maneira?
Brandon
1
@BrandonMintern Se você não possui as células da tabela, elas não funcionam no IE8 e IE9. (Veja comentário no artigo original.)
John Kurlak
Sim, as células também são necessárias no IE10. Infelizmente, no IE10 e abaixo, a .bodyaltura acaba sendo a mesma que a definida .container. A barra de rolagem vertical ainda está no lugar certo, mas .containeracaba ficando mais esticada do que queremos. Quando está em tela cheia, a parte inferior .bodyestá fora da parte inferior da tela.
Brandon
Obrigado, @JohnKurlak. É a única solução que funcionou na minha situação (o modo flexbox foi bloqueado por um comportamento de buggy na versão específica do Chrome usada pelo meu cliente)
Maksym Demidas
Piedosos ****! Eu tenho procurado por esta resposta por tanto tempo! Muito obrigado. O Flexbox não funcionou aqui, mas as células da tabela funcionaram. Surpreendente.
aabbccsmith 8/03
25

Estive procurando uma resposta para isso também. Se você tiver a sorte de poder segmentar o IE8 e superior, poderá usardisplay:table valores relacionados para obter as regras de renderização de tabelas com elementos em nível de bloco, incluindo div.

Se você tiver ainda mais sorte e seus usuários estiverem usando navegadores de primeira linha (por exemplo, se este for um aplicativo de intranet nos computadores que você controla, como o meu projeto mais recente), você poderá usar o novo Layout de caixa flexível no CSS3!

Chris
fonte
22

O que funcionou para mim (com uma div dentro de outra div e suponho em todas as outras circunstâncias) é definir o preenchimento inferior para 100%. Ou seja, adicione isso à sua css / stylesheet:

padding-bottom: 100%;
Tonye - True Vine Productions
fonte
14
100% do que? Se eu tentar isso, recebo um enorme espaço em branco e a rolagem começa a acontecer.
mlibby
100% do tamanho da janela de visualização talvez @mlibby. Se você definir seu html e corpo para 100% de altura também, a div poderá ir para 100%. Com apenas uma única div, os 100% serão relativos ao conteúdo da div. Eu não tentei com uma div aninhada.
Jess
1
Significa 100% da altura do elemento (adicionado como preenchimento do elemento), o que faz com que ele dobre a altura. Não há garantia de que irá preencher a página e, definitivamente, não a resposta para a pergunta. Como já notado, ele pode realmente preencher mais do que a janela de exibição.
Martin
2
padding-bottom: 100% conjuntos altura + 100% de contentor principal largura
Romeno
1
from w3school: especifica um preenchimento inferior em porcentagem da largura do elemento. w3schools.com/cssref/pr_padding-bottom.asp
mehdi.loa
21

Isenção de responsabilidade: a resposta aceita dá a idéia da solução, mas estou achando um pouco inchada com um invólucro desnecessário e regras de css. Abaixo está uma solução com muito poucas regras de CSS.

HTML 5

<body>
    <header>Header with an arbitrary height</header>
    <main>
        This container will grow so as to take the remaining height
    </main>
</body>

CSS

body {
  display: flex;
  flex-direction: column;
  min-height: 100vh;       /* body takes whole viewport's height */
}

main {
  flex: 1;                 /* this will make the container take the free space */
}

A solução acima usa unidades de viewport e flexbox e , portanto, é o IE10 +, desde que você use a sintaxe antiga do IE10.

Codepen para jogar: link to codepen

Ou este, para aqueles que precisam que o contêiner principal seja rolável em caso de conteúdo excedente: link para codepen

Michael P. Bazos
fonte
principal {altura: 10 px; flex: 1; estouro: auto}
Naeem Baghi
2
Depois de perder horas e testar várias abordagens, essa foi a melhor! É conciso, simples e inteligente.
marciowb
19

Agora há muitas respostas, mas achei height: 100vh;que o trabalho para trabalhar no elemento div que precisa preencher todo o espaço vertical disponível.

Dessa forma, não preciso brincar com exibição ou posicionamento. Isso foi útil ao usar o Bootstrap para criar um painel em que eu tinha uma barra lateral e uma principal. Eu queria que o principal esticasse e preencha todo o espaço vertical para que eu pudesse aplicar uma cor de fundo.

div {
    height: 100vh;
}

Suporta IE9 e superior: clique para ver o link

puiu
fonte
14
Mas 100vh soa como toda a altura, não a altura restante. E se você tiver um cabeçalho e quiser preencher o resto
Epirocks 13/18
14
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Test</title>
<style type="text/css">
body
,html
{
    height: 100%;
    margin: 0;
    padding: 0;
    color: #FFF;
}

#header
{
    float: left;
    width: 100%;
    background: red;
}

#content
{
    height: 100%;
    overflow: auto;
    background: blue;
}

</style>
</head>
<body>

    <div id="content">
        <div id="header">
                Header
                <p>Header stuff</p>
        </div>
            Content
            <p>Content stuff</p>
    </div>

</body>
</html>

Em todos os navegadores sãos, você pode colocar a div "header" antes do conteúdo, como um irmão, e o mesmo CSS funcionará. No entanto, o IE7- não interpreta a altura corretamente se o flutuador for 100% nesse caso; portanto, o cabeçalho precisa estar IN no conteúdo, como acima. O estouro: auto causará barras de rolagem duplas no IE (que sempre tem a barra de rolagem da janela de exibição visível, mas desativada), mas sem ela, o conteúdo será cortado se estourar.

Jerph
fonte
Fechar! Quase o que eu quero, exceto que eu vou ter outras coisas posicionadas no div... ou seja top: 0;, colocará algo logo abaixo do cabeçalho. Vou modificar minha pergunta novamente, porque você respondeu perfeitamente, e ainda não é o que eu quero! Vou apenas ocultar o excesso, pois o conteúdo deve caber.
Vincent McNabb
-1: Esta resposta cria uma div chamado conteúdo que cobre a tela inteira, e não o resto da tela
Casebash
11

Eu lutei com isso por um tempo e acabei com o seguinte:

Como é fácil tornar o DIV do conteúdo a mesma altura do pai, mas aparentemente difícil torná-lo a altura do pai menos a altura do cabeçalho, eu decidi fazer o conteúdo div altura completa, mas posicione-o absolutamente no canto superior esquerdo e depois defina um preenchimento para o topo que tem a altura do cabeçalho. Dessa forma, o conteúdo é exibido ordenadamente sob o cabeçalho e preenche todo o espaço restante:

body {
    padding: 0;
    margin: 0;
    height: 100%;
    overflow: hidden;
}

#header {
    position: absolute;
    top: 0;
    left: 0;
    height: 50px;
}

#content {
    position: absolute;
    top: 0;
    left: 0;
    padding-top: 50px;
    height: 100%;
}
B_G
fonte
15
E se você não souber a altura do cabeçalho?
Yugal Jindle
11

Se você puder lidar com o não suporte a navegadores antigos (ou seja, MSIE 9 ou mais antigo), poderá fazê-lo com o Módulo de layout de caixa flexível que já é W3C CR. Esse módulo também permite outros truques interessantes, como reordenar o conteúdo.

Infelizmente, o MSIE 9 ou inferior não suporta isso e você deve usar o prefixo do fornecedor para a propriedade CSS para todos os navegadores que não sejam o Firefox. Esperamos que outros fornecedores abandonem o prefixo em breve também.

Outra opção seria o CSS Grid Layout, mas que tem ainda menos suporte de versões estáveis ​​de navegadores. Na prática, apenas o MSIE 10 suporta isso.

Atualizar ano 2020 : todos os navegadores modernos suportam ambos display: flexe display: grid. O único que falta é o suporte para o subgridqual apenas é suportado pelo Firefox. Observe que o MSIE também não suporta as especificações, mas se você deseja adicionar hacks CSS específicos ao MSIE, é possível que ele se comporte. Eu sugeriria simplesmente ignorar o MSIE, porque mesmo a Microsoft diz que não deve mais ser usada.

Mikko Rantalainen
fonte
10

Solução de grade CSS

Apenas definindo a propriedade bodywith, display:gridthe grid-template-rowsusing autoe the frvalue.

* {
  margin: 0;
  padding: 0;
}

html {
  height: 100%;
}

body {
  min-height: 100%;
  display: grid;
  grid-template-rows: auto 1fr auto;
}

header {
  padding: 1em;
  background: pink;
}

main {
  padding: 1em;
  background: lightblue;
}

footer {
  padding: 2em;
  background: lightgreen;
}

main:hover {
  height: 2000px;
  /* demos expansion of center element */
}
<header>HEADER</header>
<main>MAIN</main>
<footer>FOOTER</footer>

Um guia completo para grades @ CSS-Tricks.com

Paulie_D
fonte
9

Por que não apenas assim?

html, body {
    height: 100%;
}

#containerInput {
    background-image: url('../img/edit_bg.jpg');
    height: 40%;
}

#containerControl {
    background-image: url('../img/control_bg.jpg');
    height: 60%;
}

Dar a você html e body (nessa ordem) uma altura e depois dar uma altura aos seus elementos?

Funciona para mim

Thaoms
fonte
O problema é que, se um usuário usar uma tela grande para revisar esta página e a altura do cabeçalho for fixada exatamente em 100px, menor que 40% da altura atual, haverá um grande espaço em branco entre o cabeçalho e o contexto do corpo.
Saorikido 14/05
8

Você pode realmente usar display: tablepara dividir a área em dois elementos (cabeçalho e conteúdo), onde o cabeçalho pode variar em altura e o conteúdo preenche o espaço restante. Isso funciona com toda a página, bem como quando a área é simplesmente o conteúdo de um outro elemento posicionado com positionconjunto para relative, absoluteoufixed . Funcionará enquanto o elemento pai tiver uma altura diferente de zero.

Veja este violino e também o código abaixo:

CSS:

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

p {
    margin: 0;
    padding: 0;
}

.additional-padding {
    height: 50px;
    background-color: #DE9;
}

.as-table {
    display: table;
    height: 100%;
    width: 100%;
}

.as-table-row {
    display: table-row;
    height: 100%;
}

#content {
    width: 100%;
    height: 100%;
    background-color: #33DD44;
}

HTML:

<div class="as-table">
    <div id="header">
        <p>This header can vary in height, it also doesn't have to be displayed as table-row. It will simply take the necessary space and the rest below will be taken by the second div which is displayed as table-row. Now adding some copy to artificially expand the header.</p>
        <div class="additional-padding"></div>
    </div>
    <div class="as-table-row">
        <div id="content">
            <p>This is the actual content that takes the rest of the available space.</p>
        </div>
    </div>
</div>
Greg
fonte
2
Uma boa resposta, que eu votei, mas infelizmente, não funciona com o IE8, que ainda estará disponível por muito tempo.
Vincent McNabb
Aplicativos como o Gmail usam Javascript para o dimensionamento, que é uma solução melhor que o CSS na maioria dos casos.
Vincent McNabb
Eu acho que eles estão usando Javascript porque não há outra boa solução CSS entre navegadores, não porque é melhor.
Greg
1
O @VincentMcNabb funciona no IE8 w3schools.com/cssref/pr_class_display.asp . Requer apenas a declaração DOCTYPE. Nunca soube sobre um valor de tabela para o atributo display. Solução legal. +1
Govind Rai
8
 style="height:100vh"

resolveu o problema para mim. No meu caso, apliquei isso na div requerida

Zohab Ali
fonte
6

Vincent, responderei novamente usando seus novos requisitos. Como você não se importa com o conteúdo oculto, se for muito longo, não precisa flutuar o cabeçalho. Basta colocar o excesso oculto nas tags html e body e definir a #contentaltura para 100%. O conteúdo sempre será maior que a janela de exibição pela altura do cabeçalho, mas ficará oculto e não causará barras de rolagem.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>Test</title>
    <style type="text/css">
    body, html {
      height: 100%;
      margin: 0;
      padding: 0;
      overflow: hidden;
      color: #FFF;
    }
    p {
      margin: 0;
    }

    #header {
      background: red;
    }

    #content {
      position: relative;
      height: 100%;
      background: blue;
    }

    #content #positioned {
      position: absolute;
      top: 0;
      right: 0;
    }
  </style>
</head>

<body>
  <div id="header">
    Header
    <p>Header stuff</p>
  </div>

  <div id="content">
    Content
    <p>Content stuff</p>
    <div id="positioned">Positioned Content</div>
  </div>

</body>
</html>
Jerph
fonte
Já pensei nisso. Mas também não funciona. Eu só vou ficar com um tableporque funciona. Obrigado pela atualização embora.
Vincent McNabb
5

Tente isto

var sizeFooter = function(){
    $(".webfooter")
        .css("padding-bottom", "0px")
        .css("padding-bottom", $(window).height() - $("body").height())
}
$(window).resize(sizeFooter);
Uma corrida
fonte
4

Encontrei uma solução bastante simples, porque para mim era apenas uma questão de design. Queria que o resto da página não ficasse branco abaixo do rodapé vermelho. Então, defino a cor de fundo das páginas para vermelho. E o conteúdo é colorido em branco. Com a altura do conteúdo definida como por exemplo. 20 ou 50%, uma página quase vazia não deixa a página inteira vermelha.

htho
fonte
4

Eu tive o mesmo problema, mas não consegui fazer da solução a solução com caixas flexíveis acima. Então, eu criei meu próprio modelo, que inclui:

  • um cabeçalho com um elemento de tamanho fixo
  • um rodapé
  • uma barra lateral com uma barra de rolagem que ocupa a altura restante
  • conteúdo

Usei flexboxes, mas de uma maneira mais simples, usando apenas propriedades display: flex e flex-direction: row | column :

Eu uso angular e quero que os tamanhos dos meus componentes sejam 100% do elemento pai.

A chave é definir o tamanho (em porcentagem) de todos os pais para limitar seu tamanho. No exemplo a seguir, a altura do myapp possui 100% da janela de visualização.

O componente principal possui 90% da janela de exibição, porque o cabeçalho e o rodapé têm 5%.

Publiquei meu modelo aqui: https://jsfiddle.net/abreneliere/mrjh6y2e/3

       body{
        margin: 0;
        color: white;
        height: 100%;
    }
    div#myapp
    {
        display: flex;
        flex-direction: column;
        background-color: red; /* <-- painful color for your eyes ! */
        height: 100%; /* <-- if you remove this line, myapp has no limited height */
    }
    div#main /* parent div for sidebar and content */
    {
        display: flex;
        width: 100%;
        height: 90%; 
    }
    div#header {
        background-color: #333;
        height: 5%;
    }
    div#footer {
        background-color: #222;
        height: 5%;
    }
    div#sidebar {
        background-color: #666;
        width: 20%;
        overflow-y: auto;
     }
    div#content {
        background-color: #888;
        width: 80%;
        overflow-y: auto;
    }
    div.fized_size_element {
        background-color: #AAA;
        display: block;
        width: 100px;
        height: 50px;
        margin: 5px;
    }

Html:

<body>
<div id="myapp">
    <div id="header">
        HEADER
        <div class="fized_size_element"></div>

    </div>
    <div id="main">
        <div id="sidebar">
            SIDEBAR
            <div class="fized_size_element"></div>
            <div class="fized_size_element"></div>
            <div class="fized_size_element"></div>
            <div class="fized_size_element"></div>
            <div class="fized_size_element"></div>
            <div class="fized_size_element"></div>
            <div class="fized_size_element"></div>
            <div class="fized_size_element"></div>
        </div>
        <div id="content">
            CONTENT
        </div>
    </div>
    <div id="footer">
        FOOTER
    </div>
</div>
</body>
Anthony Brenelière
fonte
4

Para aplicativos móveis, uso apenas VH e VW

<div class="container">
  <div class="title">Title</div>
  <div class="content">Content</div>
  <div class="footer">Footer</div>
</div>

.container {
  width: 100vw;
  height: 100vh;
  font-size: 5vh;
}

.title {
  height: 20vh;
  background-color: red;
}

.content {
  height: 60vh;
  background: blue;
}

.footer {
  height: 20vh;
  background: green;
}

Demonstração - https://jsfiddle.net/u763ck92/

grinmax
fonte
3
Esta não é a solução certa. vh é inconsistente em navegadores móveis. Veja aqui para obter mais detalhes: stackoverflow.com/questions/37112218/…
HarshMarshmallow
3

Girando a idéia do Sr. Alien ...

Essa parece uma solução mais limpa que a popular flex box para navegadores habilitados para CSS3.

Basta usar min-height (em vez de height) com calc () no bloco de conteúdo.

O calc () começa com 100% e subtrai as alturas dos cabeçalhos e rodapés (é necessário incluir valores de preenchimento)

Usar "min-height" em vez de "height" é particularmente útil para que ele possa trabalhar com conteúdo renderizado em javascript e estruturas JS como Angular2. Caso contrário, o cálculo não empurrará o rodapé para o final da página quando o conteúdo renderizado em javascript estiver visível.

Aqui está um exemplo simples de cabeçalho e rodapé usando 50px de altura e 20px de preenchimento para ambos.

Html:

<body>
    <header></header>
    <div class="content"></div>
    <footer></footer>
</body>

Css:

.content {
    min-height: calc(100% - (50px + 20px + 20px + 50px + 20px + 20px));
}

Claro, a matemática pode ser simplificada, mas você entendeu ...

Pat M
fonte
3

No Bootstrap:

Estilos CSS:

html, body {
    height: 100%;
}

1) Basta preencher a altura do espaço restante da tela:

<body class="d-flex flex-column">
  <div class="d-flex flex-column flex-grow-1>

    <header>Header</header>
    <div>Content</div>
    <footer class="mt-auto">Footer</footer>

  </div>
</body>

! [insira a descrição da imagem aqui


2) preencha a altura do espaço restante da tela e alinhando o conteúdo ao meio do elemento pai:

<body class="d-flex flex-column">
  <div class="d-flex flex-column flex-grow-1">

    <header>Header</header>
    <div class="d-flex flex-column flex-grow-1 justify-content-center">Content</div>
    <footer class="mt-auto">Footer</footer>

  </div>
</body>

! [insira a descrição da imagem aqui

gadolf
fonte
1

Esta é minha própria versão mínima da solução do Pebbl. Levou uma eternidade para encontrar o truque para fazê-lo funcionar no IE11. (Também testado no Chrome, Firefox, Edge e Safari.)

<!DOCTYPE html>
<html>
<head>
<style>
html {
    height: 100%;
    }
body {
    height: 100%;
    margin: 0;
    }
section {
    display: flex;
    flex-direction: column;
    height: 100%;
    }
div:first-child {
    background: gold;
    }
div:last-child {
    background: plum;
    flex-grow: 1;
    }
</style>
</head>
<body>
    <section>
      <div>FIT</div>
      <div>GROW</div>
    </section>
</body>
</html>
Michael Schade
fonte