Atualização em 2019
TL; DR: Hoje, a melhor opção é a última nesta resposta - flexbox. Tudo suporta bem e tem há anos. Vá em frente e não olhe para trás. O restante desta resposta é deixado por razões históricas.
O truque é entender do que os 100% são tirados. A leitura de especificações CSS pode ajudá-lo lá.
Para resumir uma longa história - existe um "bloco contendo" - que não é necessário como elemento pai. Simplificando, é o primeiro elemento na hierarquia que possui posição: relativa ou posição: absoluta. Ou o próprio elemento do corpo, se não houver mais nada. Portanto, quando você diz "width: 100%", ele verifica a largura do "bloco contendo" e define a largura do seu elemento para o mesmo tamanho. Se houver mais alguma coisa lá, você poderá obter o conteúdo de um "bloco contendo" maior que ele (portanto, "transbordando").
Altura funciona da mesma maneira. Com uma exceção. Você não pode obter altura para 100% da janela do navegador. O elemento de nível mais alto, contra o qual 100% pode ser calculado, é o elemento body (ou html? Não tenho certeza), e se estende apenas o suficiente para conter seu conteúdo. Especificar altura: 100% não terá efeito, pois não possui "elemento pai" contra o qual medir 100%. A janela em si não conta. ;)
Para fazer algo esticar exatamente 100% da janela, você tem duas opções:
- Use JavaScript
- Não use DOCTYPE. Essa não é uma boa prática, mas coloca os navegadores no "modo quirks", no qual você pode fazer height = "100%" nos elementos e os estenderá ao tamanho da janela. Observe que o restante da sua página provavelmente precisará ser alterado também para acomodar as alterações do DOCTYPE.
Atualização: não tenho certeza se eu não estava errado quando publiquei isso, mas isso certamente está desatualizado agora. Hoje, você pode fazer isso na sua folha de estilo: html, body { height: 100% }
e isso realmente se estenderá a toda a sua janela de visualização. Mesmo com um DOCTYPE. min-height: 100%
também pode ser útil, dependendo da sua situação.
E eu também não aconselharia ninguém a fazer um documento em modo peculiar , porque causa muito mais dores de cabeça do que os resolve. Todo navegador possui um modo quirks diferente; portanto, tornar a página com aparência consistente nos navegadores se torna duas ordens de magnitude mais difíceis. Use um DOCTYPE. Sempre. De preferência o HTML5 - <!DOCTYPE html>
. É fácil de lembrar e funciona como um encanto em todos os navegadores, mesmo nos 10 anos de idade.
A única exceção é quando você precisa oferecer suporte a algo como IE5 ou algo assim. Se você estiver lá, estará sozinho de qualquer maneira. Esses navegadores antigos não são nada parecidos com os navegadores atuais, e poucos conselhos que são dados aqui o ajudarão. Pelo lado positivo, se você estiver lá, provavelmente precisará suportar UM tipo de navegador, o que elimina os problemas de compatibilidade.
Boa sorte!
Atualização 2: Ei, faz muito tempo! 6 anos depois, novas opções estão em cena. Acabei de ter uma discussão nos comentários abaixo. Aqui estão mais truques para você que funcionam nos navegadores de hoje.
Opção 1 - posicionamento absoluto. Agradável e limpo para quando você conhece a altura exata da primeira peça.
body, html {width: 100%; height: 100%; margin: 0; padding: 0}
.first-row {position: absolute;top: 0; left: 0; right: 0; height: 100px; background-color: lime;}
.second-row {position: absolute; top: 100px; left: 0; right: 0; bottom: 0; background-color: red }
.second-row iframe {display: block; width: 100%; height: 100%; border: none;}
<div class="first-row">
<p>Some text</p>
<p>And some more text</p>
</div>
<div class="second-row">
<iframe src="https://jsfiddle.net/about"></iframe>
</div>
Algumas notas - o second-row
recipiente é necessária porque bottom: 0
e right: 0
não funciona em iframe, por algum motivo. Algo a ver com ser um elemento "substituído". Mas width: 100%
e height: 100%
funciona muito bem. display: block
é necessário porque é um inline
elemento por padrão e o espaço em branco começa a criar estouros estranhos caso contrário.
Opção 2 - tabelas. Funciona quando você não conhece a altura da primeira parte. Você pode usar <table>
tags reais ou fazê-lo da maneira mais sofisticada possível display: table
. Eu vou para o último, porque parece estar na moda nos dias de hoje.
body, html {width: 100%; height: 100%; margin: 0; padding: 0}
.row-container {display: table; empty-cells: show; border-collapse: collapse; width: 100%; height: 100%;}
.first-row {display: table-row; overflow: auto; background-color: lime;}
.second-row {display: table-row; height: 100%; background-color: red; overflow: hidden }
.second-row iframe {width: 100%; height: 100%; border: none; margin: 0; padding: 0; display: block;}
<div class="row-container">
<div class="first-row">
<p>Some text</p>
<p>And some more text</p>
</div>
<div class="second-row">
<iframe src="https://jsfiddle.net/about"></iframe>
</div>
</div>
Algumas notas - overflow: auto
garante que a linha sempre inclua todo o seu conteúdo. Caso contrário, os elementos flutuantes às vezes podem transbordar. A height: 100%
segunda linha garante que ela se expanda o máximo que puder, espremendo a primeira linha o menor possível.
Opção 3 - flexbox. O mais limpo de todos, mas com um suporte menos que estelar ao navegador. O IE10 precisará de -ms-
prefixos para as propriedades do flexbox e qualquer coisa menos não será compatível com isso.
body, html {width: 100%; height: 100%; margin: 0; padding: 0}
.row-container {display: flex; width: 100%; height: 100%; flex-direction: column; background-color: blue; overflow: hidden;}
.first-row {background-color: lime; }
.second-row { flex-grow: 1; border: none; margin: 0; padding: 0; }
<div class="row-container">
<div class="first-row">
<p>Some text</p>
<p>And some more text</p>
</div>
<iframe src="https://jsfiddle.net/about" class="second-row"></iframe>
</div>
Algumas notas - isso overflow: hidden
ocorre porque o iframe ainda gera algum tipo de estouro, mesmo display: block
nesse caso. Não é visível na visualização em tela cheia ou no editor de trechos, mas a pequena janela de visualização recebe uma barra de rolagem extra. Não faço ideia do que é isso, iframes são estranhos.