Faire Iframe pour s'adapter à 100% de la hauteur restante du conteneur
je veux concevoir une page web avec une bannière et un iframe. J'espère que l'iframe peut remplir toute la hauteur de page restante et être redimensionné automatiquement que le navigateur redimensionne. Est-il possible de le faire sans écrire de code Javascript, seulement avec CSS?
j'ai essayé de définir height:100%
sur iframe, le résultat est assez proche mais l'iframe a essayé de remplir toute la hauteur de la page, y compris la hauteur 30px
de l'élément banner div, donc j'ai obtenu vertical unneccessary défilement. Il n'est pas parfait.
Notes de mise à Jour : Excuse-moi de ne pas décrire la question, j'ai essayé CSS margin, padding attribut sur les DIV à occuper l'ensemble de la remining hauteur d'une page web avec succès, mais l'astuce ne fonctionne pas sur iframe.
<body>
<div style="width:100%; height:30px; background-color:#cccccc;">Banner</div>
<iframe src="http: //www.google.com.tw" style="width:100%; height:100%;"></iframe>
</body>
toute idée est appréciée.
26 réponses
le truc est de comprendre ce que le 100% est pris. La lecture des spécifications CSS peut vous y aider.
pour faire court une longue histoire - il y a une chose comme" contenir le bloc " - qui n'est pas nécessaire l'élément parent. Autrement dit, c'est le premier élément de la hiérarchie qui a une position:relative ou absolue. Ou l'élément du corps lui-même s'il n'y a rien d'autre. Ainsi, quand vous dites " largeur: 100%", il vérifie la largeur du "bloc contenant" et définit la largeur de votre élément de la même taille. S'il y avait quelque chose d'autre là-bas, alors vous pourriez obtenir le contenu d'un "bloc contenant" qui sont plus grands que lui-même (donc "débordant").
Hauteur fonctionne de la même manière. à une exception près. Vous ne pouvez pas obtenir la hauteur à 100% de la fenêtre du navigateur. L'élément de très haut niveau, par rapport auquel 100% peut être calculé, est le corps (ou html? pas sûr), et qui s'étend juste assez pour contenir son contenu. Spécifier hauteur:100% sur qu'il n'aura aucun effet, car il n'a pas de "parent de l'élément" permettant de mesurer les 100%. La fenêtre elle-même ne compte pas. ;)
pour faire quelque chose étirer exactement 100% de la fenêtre, vous avez deux choix:
- utiliser JavaScript
- N'utilisez pas DOCTYPE. Ce n'est pas une bonne pratique, mais cela met les navigateurs en "mode bizarreries", dans lequel vous pouvez faire hauteur= " 100%" sur les éléments et il s'étirera à la taille de la fenêtre. Notez que le reste de votre page devra probablement être modifié aussi pour s'adapter aux changements de DOCTYPE.
mise à jour: Je ne suis pas sûr si je n'avais pas déjà tort quand j'ai posté ceci, mais ceci est certainement dépassé maintenant. Aujourd'hui, vous pouvez le faire dans votre feuille de style: html, body { height: 100% }
et il s'étendra effectivement à l'ensemble de votre viewport. Même avec un DOCTYPE. min-height: 100%
pourrait également être utile, selon votre situation.
Et je ne conseillerais à personne de faire un quirks mode document de plus, soit parce qu'elle engendre la manière plus de maux de tête que les résout. Chaque navigateur a un mode de bizarreries différentes, de sorte que d'obtenir votre page à regarder régulièrement à travers les navigateurs devient deux ordres de grandeur plus difficile. Utilisez un DOCTYPE. Toujours. De préférence le HTML5 one - <!DOCTYPE html>
. C'est facile à retenir et fonctionne comme un charme sur tous les navigateurs, même les 10 ans les anciennes.
la seule exception est quand vous devez soutenir quelque chose comme IE5 ou quelque chose. Si vous êtes là, vous êtes sur votre propre, de toute façon. Ces navigateurs antiques ne sont rien comme les navigateurs aujourd'hui, et peu de conseils qui est donné ici vous aidera avec eux. Sur le côté positif, si vous êtes là, vous avez probablement juste de soutenir UN type de navigateur, qui se débarrasse des problèmes de compatibilité.
bonne chance!
Maj 2: hé, ça fait longtemps! 6 ans plus tard, de nouvelles options se présentent. Je viens d'avoir une discussion dans les commentaires ci-dessous, voici d'autres astuces pour vous qui travaillent aujourd'hui dans les navigateurs.
Option 1 - positionnement absolu. Agréable et propre pour quand vous savez que les précis de la hauteur de la première partie.
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>
quelques notes-le second-row
conteneur est nécessaire parce que bottom: 0
et right: 0
ne fonctionne pas sur iframes pour une raison quelconque. Quelque chose à faire avec un "remplacé" élément. Mais width: 100%
et height: 100%
fonctionne très bien. display: block
est nécessaire parce que c'est un élément inline
par défaut et whitespace commence à créer des dépassements bizarres autrement.
Option 2 - tables. Si vous ne connaissez pas la hauteur de la première partie. Vous pouvez utiliser actuel <table>
tags ou le faire la manière fantaisie avec display: table
. Je vais aller pour la dernière parce qu'elle semble être à la mode ces jours.
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>
quelques notes-le overflow: auto
s'assure que la rangée inclut toujours tout son contenu. Sinon éléments flottants peuvent parfois déborder. Le height: 100%
sur la deuxième rangée s'assure qu'il se dilate autant qu'il peut presser la première rangée aussi petit qu'il obtient.
Option 3 - flexbox. Le plus propre de tous, mais avec un navigateur moins que stellaire. IE10 aura besoin de préfixes -ms-
pour les propriétés flexbox, et rien de moins ne le supportera.
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>
quelques notes-le overflow: hidden
est parce que l'iframe génère encore une sorte de débordement même avec display: block
dans ce cas. Il n'est pas visible dans la vue plein écran ou l'éditeur de snippet, mais la petite fenêtre de prévisualisation obtient une barre de défilement supplémentaire. Aucune idée de ce que c'est, les iframes sont bizarres.
Nous utilisons un JavaScript pour résoudre ce problème, voici la source.
var buffer = 20; //scroll bar buffer
var iframe = document.getElementById('ifm');
function pageY(elem) {
return elem.offsetParent ? (elem.offsetTop + pageY(elem.offsetParent)) : elem.offsetTop;
}
function resizeIframe() {
var height = document.documentElement.clientHeight;
height -= pageY(document.getElementById('ifm'))+ buffer ;
height = (height < 0) ? 0 : height;
document.getElementById('ifm').style.height = height + 'px';
}
// .onload doesn't work with IE8 and older.
if (iframe.attachEvent) {
iframe.attachEvent("onload", resizeIframe);
} else {
iframe.onload=resizeIframe;
}
window.onresize = resizeIframe;
Note: ifm
est l'iframe ID
pageY()
a été créé par John Resig (l'auteur de jQuery)
une Autre façon de le faire serait d'utiliser le position: fixed;
sur le nœud parent.
Si Je ne me trompe pas, position: fixed;
lie l'élément à viewport, ainsi, une fois que vous donnez ce noeud width: 100%;
et height: 100%;
propriétés, il s'étendra sur l'écran entier. À partir de ce point, vous pouvez mettre <iframe>
étiquette à l'intérieur de celui-ci et l'étendre sur l'espace restant (à la fois en largeur et en hauteur) avec simple width: 100%; height: 100%;
instruction CSS.
body {
margin: 0px;
padding: 0px;
}
/* iframe's parent node */
div#root {
position: fixed;
width: 100%;
height: 100%;
}
/* iframe itself */
div#root > iframe {
display: block;
width: 100%;
height: 100%;
border: none;
}
<html>
<head>
<title>iframe Test</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<div id="root">
<iframe src="http://stackoverflow.com/">
Your browser does not support inline frames.
</iframe>
</div>
</body>
</html>
Vous pouvez le faire avec DOCTYPE
, mais vous devez utiliser le table
. Regardez ça:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<style>
*{margin:0;padding:0}
html, body {height:100%;width:100%;overflow:hidden}
table {height:100%;width:100%;table-layout:static;border-collapse:collapse}
iframe {height:100%;width:100%}
.header {border-bottom:1px solid #000}
.content {height:100%}
</style>
</head>
<body>
<table>
<tr><td class="header"><div><h1>Header</h1></div></td></tr>
<tr><td class="content">
<iframe src="http://google.com/" frameborder="0"></iframe></td></tr>
</table>
</body>
</html>
voici quelques approches modernes:
-
approche 1-combinaison des unités relatives de viewport /
calc()
.l'expression
calc(100vh - 30px)
représente la hauteur restante. Où100vh
est la hauteur du navigateur et de l'utilisation decalc()
effectivement déplace la hauteur de la un autre élément.body { margin: 0; } .banner { background: #f00; height: 30px; } iframe { display: block; background: #000; border: none; height: calc(100vh - 30px); width: 100%; }
<div class="banner"></div> <iframe></iframe>
Soutien pour
calc()
ici ; l'appui à la fenêtre d'affichage des unités relatives ici .
-
approche 2-Approche Flexbox
définit
display
de l'élément parent commun àflex
, avecflex-direction: column
(en supposant que vous voulez que les éléments soient empilés les uns sur les autres). Ensuite, réglezflex-grow: 1
sur l'enfantiframe
élément pour remplir l'espace restant.body { margin: 0; } .parent { display: flex; flex-direction: column; min-height: 100vh; } .parent .banner { background: #f00; width: 100%; height: 30px; } .parent iframe { background: #000; border: none; flex-grow: 1; }
<div class="parent"> <div class="banner"></div> <iframe></iframe> </div>
depuis cette approche a moins de support 1 , je suggère d'adopter l'approche susmentionnée.
1 bien qu'il semble fonctionner dans Chrome/FF, il ne fonctionne pas dans IE (la première méthode fonctionne dans tous les navigateurs actuels).
peut-être que cela a déjà été répondu (quelques réponses ci-dessus sont "correctes" façons de le faire), mais j'ai pensé que je voudrais juste ajouter ma solution aussi bien.
notre iFrame est chargé dans un div, donc j'ai eu besoin de quelque chose d'autre que la fenêtre.hauteur. Et vu que notre projet repose déjà fortement sur jQuery, je trouve que c'est la solution la plus élégante:
$("iframe").height($("#middle").height());
où bien sûr "# middle " est l'id du div. La seule chose supplémentaire que vous aurez besoin de faire se rappeler ce changement de taille lorsque l'utilisateur redimensionne la fenêtre.
$(window).resize(function() {
$("iframe").height($("#middle").height());
});
le code MichAdel fonctionne pour moi mais j'ai fait quelques modifications mineures pour le faire fonctionner correctement.
function pageY(elem) {
return elem.offsetParent ? (elem.offsetTop + pageY(elem.offsetParent)) : elem.offsetTop;
}
var buffer = 10; //scroll bar buffer
function resizeIframe() {
var height = window.innerHeight || document.body.clientHeight || document.documentElement.clientHeight;
height -= pageY(document.getElementById('ifm'))+ buffer ;
height = (height < 0) ? 0 : height;
document.getElementById('ifm').style.height = height + 'px';
}
window.onresize = resizeIframe;
window.onload = resizeIframe;
voilà ce que j'ai fait. J'ai eu le même problème et j'ai fini par chercher des ressources sur le web pendant des heures.
<style type="text/css">
html, body, div, iframe { margin:0; padding:0; height:100%; }
iframe { position:fixed; display:block; width:100%; border:none; }
</style>
j'ai ajouté ceci à la section tête.
s'il vous plaît noter que mon iframe est situé à l'intérieur de la cellule centrale d'une table qui a 3 lignes et 1 colonne.
essayez ce qui suit:
<iframe name="" src="" width="100%" style="height: 100em"/>
il a travaillé pour moi
vous pouvez le faire avec html / css comme ceci:
<body>
<div style="width:100%; height:30px; background-color:#cccccc;">Banner</div>
<iframe src="http: //www.google.com.tw" style="position:fixed;top:30px;bottom:0px;width:100%;"></iframe>
</body>
c'est vrai, vous montrez une iframe avec 100% de hauteur par rapport à son conteneur: la carrosserie.
essayez ceci:
<body>
<div style="width:100%; height:30px; background-color:#cccccc;">Banner</div>
<div style="width:100%; height:90%; background-color:transparent;">
<iframe src="http: //www.google.com.tw" style="width:100%; height:100%;">
</iframe>
</div>
</body>
bien sûr, changez la hauteur du deuxième div à la hauteur que vous voulez.
nouveau en HTML5: utiliser calc (sur la hauteur)
<html style="width:100%; height:100%; margin: 0px; padding: 0px;">
<body style="width:100%; height:100%; margin: 0px; padding: 0px;">
<div style="width:100%; height:30px; background-color:#cccccc;">Banner</div>
<iframe src="http://www.google.com.tw" style="width:100%; height: calc(100% - 30px);"></iframe>
</body>
</html>
j'ai utilisé display:table pour corriger un problème similaire. Il presque fonctionne pour cela, laissant une petite barre de défilement verticale. Si vous essayez de peupler cette colonne flexible avec quelque chose d'autre qu'une iframe il fonctionne très bien (pas
prendre le HTML suivant
<body>
<div class="outer">
<div class="banner">Banner</div>
<div class="iframe-container">
<iframe src="http: //www.google.com.tw" style="width:100%; height:100%;border:0;"></iframe>
</div>
</div>
</body>
changer le div externe pour utiliser display:table et s'assurer qu'il a une largeur et une hauteur réglée.
.outer {
display: table;
height: 100%;
width: 100%;
}
faites de la bannière un table-row et réglez sa hauteur à ce que votre préférence est:
.banner {
display: table-row;
height: 30px;
background: #eee;
}
Ajouter un div supplémentaire autour de votre iframe (ou quel que soit le contenu dont vous avez besoin) et en faire une rangée de table avec une hauteur fixée à 100% (le réglage de sa hauteur est critique si vous voulez intégrer une iframe pour remplir la hauteur)
.iframe-container {
display: table-row;
height: 100%;
}
ci-dessous est un jsfiddle le montrant au travail (sans iframe parce que cela ne semble pas fonctionner dans le violon)
je pense que vous avez un problème conceptuel ici. Pour dire "j'ai essayé hauteur fixe: 100% Sur iframe, le résultat est assez proche mais l'iframe a essayé de remplir toute la page " , Eh bien, quand" 100% "n'a-t-il pas été égal à"Entier"?
vous avez demandé à l'iframe de remplir toute la hauteur de son conteneur (qui est le corps) mais malheureusement il a un frère de niveau de bloc dans le
Ce que je pense de vous signifie que vous souhaiteriez que l'iframe à la consommation ce qui est à gauche comme des images et des cellules de tableau peut, c'est à dire height="*". IIRC ce qui n'existe pas.
malheureusement, à ma connaissance, il n'y a aucun moyen de mélanger/calculer/soustraire efficacement les unités absolues et relatives non plus, donc je pense que vous êtes réduit à deux options:
-
positionnez absolument votre div, qui va le prendre hors du récipient, l'iframe seul consommera il est conteneurs de hauteur. Cela vous laisse avec toutes sortes d'autres problèmes bien, mais peut-être que ce que vous êtes faire de l'opacité ou l'alignement serait OK.
-
alternativement vous devez spécifier un % de hauteur pour le div et de réduire la hauteur de l'iframe par beaucoup. Si la hauteur absolue est vraiment importantes que vous aurez besoin d'appliquer que pour un élément enfant de la div plutôt.
ayant essayé la route css pendant un certain temps, j'ai fini par écrire quelque chose de assez basique à jQuery qui a fait le travail pour moi:
function iframeHeight() {
var newHeight = $j(window).height();
var buffer = 180; // space required for any other elements on the page
var newIframeHeight = newHeight - buffer;
$j('iframe').css('height',newIframeHeight); //this will aply to all iframes on the page, so you may want to make your jquery selector more specific.
}
// When DOM ready
$(function() {
window.onresize = iframeHeight;
}
testé en IE8, Chrome, Firefox 3.6
il fonctionnera avec le code ci-dessous mentionné
<iframe src="http: //www.google.com.tw"style="position: absolute; height: 100%; border: none"></iframe>
réponse similaire de @MichAdel, mais j'utilise JQuery et plus élégant.
<script type="text/javascript">
$(document).ready(function() {
var $iframe = $('#iframe_id')[0];
// Calculate the total offset top of given jquery element
function totalOffsetTop($elem) {
return $elem.offsetTop + ($elem.offsetParent ? totalOffsetTop($elem.offsetParent) : 0);
}
function resizeIframe() {
var height = window.innerHeight || document.body.clientHeight || document.documentElement.clientHeight;
height -= totalOffsetTop($iframe);
$iframe.height = Math.max(0, height) + 'px';
}
$iframe.onload = resizeIframe();
window.onresize = resizeIframe;
});
</script>
iframe_id
est L'ID de la balise iframe
vous pouvez le faire en mesurant la taille du corps lors d'événements de chargement/redimensionnement et en réglant la hauteur sur la hauteur (hauteur maximale - Hauteur de la bannière).
notez qu'actuellement dans IE8 Beta2 vous ne pouvez pas faire ceci onresize car cet événement est actuellement cassé dans IE8 Beta2.
bien que je convienne que JS semble une meilleure option, Je n'ai qu'une solution qui fonctionne un peu CSS. L'inconvénient, c'est que si vous devez ajouter du contenu à votre iframe document html fréquemment, vous devrez adapter un pourcentage dans le temps.
Solution:
Essayer de ne pas spécifier toute la hauteur pour vos documents html,
html, body, section, main-div {}
alors coder seulement ceci:
#main-div {height:100%;}
#iframe {height:300%;}
note: le div doit être votre section principale.
cela devrait fonctionner relativement. l'iframe calcule exactement 300% de la hauteur visible de la fenêtre. Si le contenu html du 2e document (dans l'iframe) est plus petit en hauteur que 3 fois la hauteur de votre navigateur, il fonctionne. Si vous n'avez pas besoin d'ajouter du contenu fréquemment à ce document, c'est une solution permanente et vous pouvez juste trouver votre propre % nécessaire en fonction de votre hauteur de contenu.
Cela fonctionne parce qu'il empêche le 2e document html (celui qui est intégré) d'hériter de sa hauteur par rapport au document HTML parent. Il l'empêche parce que nous n'avons pas spécifié de hauteur pour les deux. Quand nous donnons un % à l'enfant il cherche son parent, sinon, il prend sa hauteur de contenu. Et seulement si les autres containers n'ont pas la taille voulue, d'après ce que j'ai essayé.
l'attribut seamless "est une nouvelle norme visant à résoudre ce problème:
http://www.w3schools.com/tags/att_iframe_seamless.asp
lors de l'attribution de cet attribut, il supprimera les bordures et les barres de défilement et taille l'iframe à sa taille de contenu. bien qu'il ne soit pris en charge que dans Chrome et dernier Safari
pour en savoir plus, cliquez ici: HTML5 iFrame Seamless Attribut
a simple jQuery solution
utilisez ceci dans un script à l'intérieur de la page iframed
$(function(){
if(window != top){
var autoIframeHeight = function(){
var url = location.href;
$(top.jQuery.find('iframe[src="'+ url +'"]')).css('height', $('body').height()+4);
}
$(window).on('resize',autoIframeHeight);
autoIframeHeight();
}
}
vous ne pouvez pas définir la hauteur iframe en % parce que la hauteur de votre corps parent n'est pas 100% alors faire la hauteur parent comme 100% et ensuite appliquer la hauteur iframe 100%
For eg.
<html>
<head>
<style>
html,body{height:100%}
</style>
</head>
<body>
<iframe src="http://www.quasarinfosystem.com" height="100%" width="100%" ></iframe>
</body>
</html>
Si vous avez accès au contenu de l'iframe qui sera chargé, vous pouvez dire à ses parents pour redimensionner chaque fois qu'il change..
$(window).resize(function() {
$(parent.document)
.find("iframe")
.css("height", $("body").css("height"));
}).trigger("resize");
Si vous avez plus d'un iframe sur la page, vous pouvez avoir besoin d'utiliser des id ou d'autres intelligent méthodes pour améliorer .trouver ("iframe") de sorte que vous sélectionnez le bon.
je pense que la meilleure façon d'atteindre ce scénario en utilisant la position css. définissez la position par rapport à votre div parent et la position:absolue à votre iframe.
.container{
width:100%;
position:relative;
height:500px;
}
iframe{
position:absolute;
width:100%;
height:100%;
}
<div class="container">
<iframe src="http://www.w3schools.com">
<p>Your browser does not support iframes.</p>
</iframe>
</div>
pour d'autres padding et Marge question maintenant un jour CSS3 calc() est très avancé et la plupart du temps compatible à tous les navigateurs ainsi.
vérifier calc()
pourquoi ne pas faire ceci (avec un ajustement mineur pour le rembourrage/les marges du corps)
<script>
var oF = document.getElementById("iframe1");
oF.style.height = document.body.clientHeight - oF.offsetTop - 0;
</script>