使Iframe适应容器剩余高度的100%


260

我想设计一个带有横幅和iframe的网页。我希望iframe可以填满所有剩余的页面高度,并在浏览器调整大小时自动调整大小。是否可以仅使用CSS而无需编写Javascript代码来完成它?

我尝试height:100%在iframe上进行设置,结果非常接近,但是iframe尝试填充整个页面高度,包括30pxbanner div元素的高度,所以我得到了不必要的垂直滚动条。这不是完美的。

更新说明:对不起,我没有很好地描述问题,我尝试使用CSS边距,DIV上的padding属性成功占据网页的整个刷新高度,但该技巧在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>

任何想法表示赞赏。

Answers:


236

2019年更新

TL; DR:今天,最好的选择是这个答案中的最后一个-flexbox。一切都很好地支持它,并且已经有很多年了。为此,不要回头。由于历史原因,其余答案均保留下来。


诀窍是要了解100%是什么。阅读CSS规范可以为您提供帮助。

长话短说-有一个“包含块”之类的东西-父元素不是必需的。简而言之,这是层次结构中具有position:relative或position:absolute的第一个元素。如果没有其他内容,则为body元素本身。因此,当您说“ width:100%”时,它将检查“包含块”的宽度,并将元素的宽度设置为相同的大小。如果那里还有其他东西,那么您可能会获得比其自身大的“包含块”的内容(因此“溢出”)。

高度的工作方式相同。除了一个例外。您无法将浏览器窗口的高度提高到100%。最上层的元素(可以计算出100%)是body(或html?不确定)元素,其拉伸范围足以容纳其内容。在其上指定height:100%将无效,因为它没有要对其进行100%测量的“父元素”。窗口本身不计算在内。;)

要使某物精确地延伸到窗口的100%,您有两种选择:

  1. 使用JavaScript
  2. 不要使用DOCTYPE。这不是一个好习惯,但是它会使浏览器处于“怪癖模式”,在这种模式下,您可以对元素执行height =“ 100%”并将其扩展到窗口大小。请注意,页面的其余部分可能也必须进行更改以适应DOCTYPE的更改。

更新:我不确定发布此消息时是否还不错,但是现在肯定已经过时了。今天,您可以在样式表中执行此操作:html, body { height: 100% }它实际上将扩展到整个视口。即使使用DOCTYPE。min-height: 100%视您的情况而定也可能有用。

而且我也不建议任何人再做一个怪异模式的文档,因为它造成的头痛比解决它们的方式更多。每种浏览器都有不同的怪癖模式,因此要使页面在各种浏览器中保持一致就变得困难了两个数量级。使用DOCTYPE。总是。最好是HTML5 one- <!DOCTYPE html>。它易于记忆,并且在所有浏览器(甚至10岁的浏览器)中都像魅力一样起作用。

唯一的例外是当您必须支持IE5之类的东西时。如果您在那里,那么无论如何您都是自己的。那些古老的浏览器与今天的浏览器完全不同,这里给出的建议很少会对您有所帮助。从好的方面来说,如果您在那里,则可能只需要支持一种浏览器即可解决兼容性问题。

祝好运!

更新2:嘿,已经很久了!6年后,新的选择出现了。我刚刚在下面的评论中进行了讨论,下面是在当今浏览器中可以使用的更多技巧。

选项1-绝对定位。当您知道第一部分的精确高度时,它非常干净。

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>

一些注意事项-在second-row需要的容器,因为bottom: 0right: 0没有在内部框架出于某种原因的工作。与“替换”元素有关。但是width: 100%height: 100%工作正常。display: block是必需的,因为inline默认情况下它是一个元素,否则空格会开始产生怪异的溢出。

选项2-表格。当您不知道第一部分的高度时可以使用。您可以使用实际<table>标签,也可以使用精美的标签display: table。我会选择后者,因为这几天似乎很流行。

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>

一些注意事项- overflow: auto确保该行始终包含其所有内容。否则,浮动元素有时会溢出。在height: 100%第二行确保它扩展一样,因为它可以挤压第一排的小,因为它得到。

选项3 -flexbox。其中最干净的一种,但对浏览器的支持不足。IE10 -ms-的flexbox属性需要前缀,而其他任何东西都将根本不支持它。

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>

一些注意事项-这overflow: hidden是因为即使display: block在这种情况下,iframe仍然会产生某种程度的溢出。在全屏视图或代码片段编辑器中看不到它,但是小的预览窗口有一个额外的滚动条。不知道那是什么,iframe很奇怪。


@sproketboy嗯,这是W3C建议。而且这甚至不是最坏的情况,也没有很长的路要走。
约翰

那么,我们将其放置在IFrame页面的样式表中还是包含IFrame的父页面的样式表中?
Mathias Lykkegaard Lorenzen 2015年

1
太好了,谢谢!flexbox确实是最干净的,但是这些表也很容易学习,并且似乎可以正常工作:jsfiddle.net/dmitri14/1uqh3zgx/2
Dmitri Zaitsev

1
可能值得将最新更新移至此答案的顶部。我必须仔细研究整个问题才能获得最佳答案,flexbox。
原谅的

2
@forgivenson-足够真实。在此答案的开头添加了注释。
Vilx-

68

我们使用JavaScript解决此问题;这是来源。


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;

注意:ifm是iframe ID

pageY() 由John Resig(jQuery的作者)创建


49

另一种方法是使用position: fixed;on父节点。
如果我没记错的话,position: fixed;请将元素绑定到视口,这样,一旦您指定了该节点width: 100%;height: 100%;属性,它将覆盖整个屏幕。从这一点开始,您可以<iframe>使用简单的width: 100%; height: 100%;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>


1
这如何达到“剩余”高度?
EricG

3
我注意到您还需要添加position: fixed到iframe中。
0xF

谢谢您,将我的SSRS报告高度调高了,避免了第二天的自杀。
Mike D

1
没有可见的滚动条
andrej

完美-您能进一步解释css'>'吗,例如div#root> iframe,因为我不熟悉它并且找不到参考资料
Datadimension '17

40

以下是一些现代方法:


  • 方法1- 视口相对单位 /的组合calc()

    该表达式calc(100vh - 30px)表示剩余高度。100vh浏览器的高度在哪里,使用calc()有效地替换了其他元素的高度。

    这里的例子

    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>

    支持calc()这里 ; 在此支持视口相关单位


  • 方法2-Flexbox方法

    这里的例子

    display共同父元素的设置为flex,以及flex-direction: column(假设您希望元素堆叠在一起)。然后flex-grow: 1在子iframe元素上进行设置,以使其填充剩余空间。

    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>

    由于此方法的支持较少1,因此建议您使用上述方法。

1 尽管它似乎可以在Chrome / FF中使用,但在IE中却无法使用(第一种方法适用于当前所有浏览器)。


3
无论是工作还是IMO,这里提到的两个选项都是最好的方法。我更喜欢该flexbox选项,因为calc您需要知道从中扣除的空间量vh。有了flexbox一个简单的flex-grow:1做了。
Kilmazing

39

您可以使用它DOCTYPE,但必须使用table。看一下这个:

<!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>

1
至少它不需要js!但这对网络安全吗?
2011年

1
此解决方案的缺点是html,body {overflow:hidden;}将删除页面滚动。
2011年

我正在尝试在上述代码中添加页脚,但页脚未显示。你能帮忙吗?
Akshay Raut

18

也许已经回答了(上面的一些回答是“正确”的方法),但是我想我也应该添加解决方案。

我们的iFrame是在div中加载的,因此我需要window.height之后的其他内容。看到我们的项目已经高度依赖jQuery,我发现这是最优雅的解决方案:

$("iframe").height($("#middle").height());

当然,“#middle”是div的ID。您唯一需要做的就是在用户调整窗口大小时调用此大小更改。

$(window).resize(function() {
    $("iframe").height($("#middle").height());
});

7

这就是我所做的。我遇到了同样的问题,最终在网上搜索了几个小时的资源。

<style type="text/css">
   html, body, div, iframe { margin:0; padding:0; height:100%; }
   iframe { position:fixed; display:block; width:100%; border:none; }
</style>

我将此添加到头部。

请注意,我的iframe位于具有3行1列的表格的中间单元内。


您的代码仅适用于包含IFRAME的height为100%的TD。如果表格包含在DIV元素中,它将起作用,因为您具有所有div都具有height:100%的样式。
Nikola Petkanski 2011年

6

MichAdel代码对我有用,但我做了一些小的修改以使其正常工作。

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;

4

没错,您所展示的iframe相对于其容器:主体的高度为100%。

试试这个:

<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>

当然,将第二个div的高度更改为所需的高度。


8
30px + 90%!= 100%
stepancheg,2010年

1
可以使用calc(100%-30px)而不是90%
贾斯汀E

4

尝试以下方法:

<iframe name="" src="" width="100%" style="height: 100em"/>

它对我有用


4
不填充父级,只是在iframe上放了一个很大的高度。
2015年

3

您可以使用html / css这样进行操作:

<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>

2

HTML5的新功能:使用calc(高度)

<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>

2

我使用display:table来解决类似的问题。它几乎适用于这一点,留下一个小的垂直滚动条。如果您尝试使用除iframe之外的其他内容填充该灵活列,则它可以正常工作(不

采取以下HTML

<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>

将外部div更改为使用display:table并确保已设置宽度和高度。

.outer {
  display: table;
  height: 100%;
  width: 100%;
}

将横幅设置为表格行,并将其高度设置为您的首选项:

.banner {
  display: table-row;
  height: 30px;
  background: #eee;
}

在iframe(或所需的任何内容)周围添加一个额外的div,并将其设置为高度设置为100%的表格行(如果要嵌入iframe以填充高度,则设置其高度至关重要)

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

下面是一个jsfiddle,显示了它的工作状态(没有iframe,因为在小提琴中似乎不起作用)

https://jsfiddle.net/yufceynk/1/


1

我认为您在这里有一个概念上的问题。要说“我尝试在iframe上设置height:100%,结果非常接近,但iframe试图填满整个页面”,那么,何时“ 100%”不等于“整个”?

您已要求iframe填充其容器(即主体)的整个高度,但不幸的是,它在<div>中具有块级同级,要求将其设为30px大。因此,现在要求将父容器的总尺寸设置为100%+ 30px> 100%!因此,滚动条。

我想您的意思是,您希望iframe 像框架和表格单元格一样使用剩余的东西,即height =“ *”。IIRC这不存在。

不幸的是,据我所知,也没有办法有效地混合/计算/减去绝对和相对单位,因此我认为您只能选择两种:

  1. 绝对放置div,将其从容器中取出,这样仅iframe便会消耗其容器高度。尽管这会给您带来其他各种问题,但是对于您正在做的不透明度或对齐方式来说,这可能没问题。

  2. 另外,您需要为div指定高度百分比,并将iframe的高度减少那么多。如果绝对高度真的很重要,则需要将其应用于div的子元素。


1

经过一段时间的css路由,我最终在jQuery中写了一些相当基本的东西,为我完成了这项工作:

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;
}

在IE8,Chrome,Firefox 3.6中测试


1

它将与下面提到的代码一起使用

<iframe src="http: //www.google.com.tw"style="position: absolute; height: 100%; border: none"></iframe>

1

@MichAdel的答案与此类似,但我使用的是JQuery,它更优雅。

<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 是iframe广告代码的ID


0

您可以通过在加载/调整大小事件中测量主体尺寸并将高度设置为(全高-标语高度)来做到这一点。

请注意,当前在IE8 Beta2中您无法按此大小执行此操作,因为该事件当前在IE8 Beta2中已中断。



0

虽然我同意JS似乎是一个更好的选择,但我有一个仅CSS的有效解决方案。它的缺点是,如果您必须经常向iframe html文档中添加内容,则必须调整一个百分比的谷值时间。

解:

尝试不要同时为html文档指定任何高度,

html, body, section, main-div {}

然后只编码:

#main-div {height:100%;}
#iframe {height:300%;}

注意:div应该是您的主要部分。

这应该相对有效。iframe确实会准确计算可见窗口高度的300%。如果第二个文档(在iframe中)的html内容的高度小于浏览器高度的3倍,则可以正常工作。如果您不需要经常向该文档添加内容,这是一个永久性的解决方案,您可以根据自己的内容高度找到自己所需的%。

之所以有效,是因为它阻止了第二个html文档(一个被嵌入)从父html文档继承其高度。它可以防止出现这种情况,因为我们没有为它们两个都指定高度。当我们给孩子一个%的时候,它会寻找它的父母,如果不是,它将取其内容高度。而且只有在其他容器没有指定高度的情况下,我才尝试这样做。



0

一个简单的jQuery解决方案

在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();
    }

}

0

您无法以%设置iframe高度,因为您的父代身体高度不是100%,因此请将父代高度设置为100%,然后将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>

0

如果您有权访问将要加载的iframe的内容,则可以在调整大小时告诉其父项重新调整大小。

    $(window).resize(function() {
        $(parent.document)
            .find("iframe")
            .css("height", $("body").css("height"));        
    }).trigger("resize");

如果页面上有多个iframe,则可能需要使用id或其他巧妙的方法来增强.find(“ iframe”),以便选择正确的iframe。


0

我认为使用CSS位置实现此方案的最佳方法。设置相对于您的父div的位置和position:absolute到您的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>

对于其他填充和边距问题,现在css3 calc()非常先进,并且几乎与所有浏览器都兼容。

检查calc()


0

为什么不这样做(对主体填充/边距进行细微调整)

<script>
  var oF = document.getElementById("iframe1");
  oF.style.height = document.body.clientHeight - oF.offsetTop - 0;
</script>

您需要更换-0+'px'结尾。可以在手机上使用吗?
Dmitri Zaitsev
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.