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.
Usamos um JavaScript para resolver esse problema; aqui está a fonte.
Nota:
ifm
é o ID do iframepageY()
foi criado por John Resig (o autor do jQuery)fonte
Outra maneira de fazer isso seria usar o
position: fixed;
nó pai.Se não me engano,
position: fixed;
vincula o elemento à viewport; assim, depois de fornecer esse nówidth: 100%;
eheight: 100%;
propriedades, ele se estenderá por toda a tela. A partir deste ponto, você pode colocar a<iframe>
tag dentro dela e estendê-la pelo espaço restante (em largura e altura) com simpleswidth: 100%; height: 100%;
instruções CSS.Código de exemplo
fonte
position: fixed
ao iframe.Aqui estão algumas abordagens modernas:
Abordagem 1 - Combinação de unidades relativas da janela de visualização /
calc()
.A expressão
calc(100vh - 30px)
representa a altura restante. Onde100vh
está a altura do navegador e o uso decalc()
efetivamente desloca a altura do outro elemento.Exemplo Aqui
Suporte para
calc()
aqui ; suporte para unidades relativas da janela de visualização aqui .Abordagem 2 - Abordagem Flexbox
Exemplo Aqui
Defina o
display
elemento pai comum comoflex
, junto comflex-direction: column
(supondo que você queira que os elementos sejam empilhados uns sobre os outros). Em seguida, definaflex-grow: 1
oiframe
elemento filho para que ele preencha o espaço restante.Como essa abordagem tem menos suporte 1 , sugiro seguir a abordagem mencionada acima.
1 Embora pareça funcionar no Chrome / FF, não funciona no IE (o primeiro método funciona em todos os navegadores atuais).
fonte
flexbox
opção porque comcalc
você precisa saber a quantidade de espaço a deduzir dovh
. Comflexbox
um simplesflex-grow:1
faz.Você pode fazer isso com
DOCTYPE
, mas precisa usartable
. Veja isso:fonte
Talvez isso já tenha sido respondido (algumas respostas acima são formas "corretas" de fazer isso), mas pensei em adicionar minha solução também.
Nosso iFrame é carregado dentro de uma div, portanto, eu precisava de algo mais do que window.height. E vendo o nosso projeto já depende muito do jQuery, acho que essa é a solução mais elegante:
Onde é claro que "#middle" é o ID da div. A única coisa extra que você precisa fazer é recuperar essa alteração de tamanho sempre que o usuário redimensionar a janela.
fonte
Aqui está o que eu fiz. Eu tive o mesmo problema e acabei pesquisando recursos na web por horas.
Eu adicionei isso à seção principal.
Observe que meu iframe está localizado dentro da célula do meio de uma tabela que possui 3 linhas e 1 coluna.
fonte
O código MichAdel funciona para mim, mas eu fiz algumas pequenas modificações para fazê-lo funcionar corretamente.
fonte
Está certo, você está mostrando um iframe com 100% de altura em relação ao seu contêiner: o corpo.
Tente o seguinte:
Evidentemente, altere a altura da segunda div para a altura desejada.
fonte
tente o seguinte:
funcionou para mim
fonte
Você pode fazer isso com html / css assim:
fonte
Novo no HTML5: use calc (na altura)
fonte
Eu usei display: table para corrigir um problema semelhante. É quase funciona para isso, deixando uma pequena barra de rolagem vertical. Se você está tentando preencher essa coluna flexível com algo diferente de um iframe, funciona bem (não
Pegue o seguinte HTML
Altere a div externa para usar display: table e verifique se a largura e a altura estão definidas.
Torne o banner uma linha da tabela e defina sua altura para qualquer que seja sua preferência:
Adicione uma div extra ao redor do seu iframe (ou qualquer conteúdo que você precise) e torne-o uma linha de tabela com altura definida como 100% (definir sua altura é essencial se você deseja incorporar um iframe para preencher a altura)
Abaixo está um jsfiddle mostrando-o no trabalho (sem um iframe porque isso não parece funcionar no violino)
https://jsfiddle.net/yufceynk/1/
fonte
Eu acho que você tem um problema conceitual aqui. Para dizer "Tentei definir a altura: 100% no iframe, o resultado está bem próximo, mas o iframe tentou preencher a página inteira" , bem, quando "100%" não foi igual a "todo"?
Você pediu ao iframe para preencher toda a altura do contêiner (que é o corpo), mas infelizmente ele tem um irmão no nível de bloco no <div> acima do qual você pediu 30px de tamanho. Agora, o total do contêiner pai está sendo solicitado a dimensionar para 100% + 30px> 100%! Daí barras de rolagem.
O que eu acho que você quer dizer é que você gostaria que o iframe consumisse o que resta como quadros e células da tabela, ou seja, height = "*". IIRC isso não existe.
Infelizmente, até onde sei, também não há como misturar / calcular / subtrair efetivamente unidades absolutas e relativas, então acho que você está reduzido a duas opções:
Posicione absolutamente sua div, que a retirará do contêiner, de modo que somente o iframe consuma a altura do contêiner. Isso deixa você com todos os tipos de outros problemas, mas talvez o que você está fazendo opacidade ou alinhamento esteja ok.
Como alternativa, você precisa especificar uma% de altura para a div e reduzir em muito a altura do iframe. Se a altura absoluta for realmente tão importante, você precisará aplicá-la a um elemento filho da div.
fonte
Tendo tentado a rota css por um tempo, acabei escrevendo algo bastante básico no jQuery que fez o trabalho para mim:
Testado no IE8, Chrome, Firefox 3.6
fonte
Ele funcionará com o código abaixo mencionado
fonte
Resposta semelhante do @MichAdel, mas estou usando o JQuery e mais elegante.
iframe_id
é o ID da tag iframefonte
Você pode fazer isso medindo o tamanho do corpo em eventos de carregamento / redimensionamento e configurando a altura para (altura total - altura do banner).
Observe que atualmente no IE8 Beta2 você não pode fazer isso em redimensionamento, pois esse evento está quebrado no IE8 Beta2.
fonte
ou você pode ir à moda antiga e usar um conjunto de quadros, talvez:
fonte
Embora eu concorde que o JS parece uma opção melhor, eu tenho uma solução que funciona apenas com CSS. A desvantagem disso é que, se você precisar adicionar conteúdo ao seu documento HTML iframe com frequência, precisará adaptar uma porcentagem durante o tempo.
Solução:
Tente não especificar nenhuma altura para AMBOS os seus documentos html,
codifique apenas isso:
nota: a div deve ser sua seção principal.
Isso deve funcionar relativamente. o iframe calcula exatamente 300% da altura da janela visível. Se o conteúdo html do 2º documento (no iframe) tiver uma altura menor que 3 vezes a altura do navegador, ele funcionará. Se você não precisar adicionar conteúdo com frequência a esse documento, essa é uma solução permanente e você poderá encontrar a% necessária, de acordo com a altura do conteúdo.
Isso funciona porque evita que o segundo documento html (aquele incorporado) herda sua altura do documento html pai. Isso evita porque não especificamos uma altura para os dois. Quando damos um% ao filho, ele procura seu pai, caso contrário, ele assume a altura do conteúdo. E somente se os outros contêineres não tiverem alturas, pelo que tentei.
fonte
O atributo " sem costura " é um novo padrão que visa solucionar esse problema:
http://www.w3schools.com/tags/att_iframe_seamless.asp
Ao atribuir esse atributo, ele removerá bordas e barras de rolagem e dimensionará o iframe para o tamanho do conteúdo. embora seja suportado apenas no Chrome e no Safari mais recente
mais sobre isso aqui: HTML5 iFrame Seamless Attribute
fonte
Uma solução simples jQuery
Use isso em um script dentro da página iframed
fonte
você não pode definir a altura do iframe em% porque a altura do corpo do pai não é 100%. Portanto, torne a altura do pai como 100% e aplique a altura do iframe 100%
fonte
Se você tiver acesso ao conteúdo do iframe que será carregado, poderá solicitar que o pai seja redimensionado sempre que ele for redimensionado.
Se você tiver mais de um iframe na página, poderá ser necessário usar IDs ou outros métodos inteligentes para aprimorar .find ("iframe") para selecionar o correto.
fonte
Eu acho que a melhor maneira de alcançar esse cenário usando a posição css. defina a posição em relação ao div principal e a posição: absoluta ao iframe.
para outros problemas de preenchimento e margem nos dias de hoje, o css3 calc () é muito avançado e também compatível com todos os navegadores.
verifique calc ()
fonte
Por que não fazer isso (com pequenos ajustes para preenchimento / margens do corpo)
fonte
-0
por+'px'
no final. Funciona no celular?