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

Dar*_*ead 236 html css iframe

我想设计一个带有横幅和iframe的网页.我希望iframe可以填充所有剩余的页面高度,并在浏览器调整大小时自动调整大小.是否有可能在没有编写Javascript代码的情况下完成它,只有CSS?

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

更新说明:请原谅我没有好好描述这个问题,我在DIV上尝试了CSS margin,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>
Run Code Online (Sandbox Code Playgroud)

任何想法都表示赞赏.

Vil*_*lx- 207

诀窍是要了解100%的含义.阅读CSS规范可以帮助你.

长话短说 - 有一个"包含块"的东西 - 这不是父元素.简单地说,它是层次结构中具有位置的第一个元素:relative或position:absolute.或者身体元素本身,如果没有别的.因此,当您说"width:100%"时,它会检查"包含块"的宽度,并将元素的宽度设置为相同的大小.如果那里还有其他东西,那么你可能会得到一个比自身大的"包含块"的内容(因此"溢出").

高度以相同的方式工作.有一个例外.您无法获得100%的浏览器窗口高度.可以计算100%的最高级别元素是body(或html?不确定)元素,并且该元素足以包含其内容.指定高度:100%对它没有影响,因为它没有"父元素"来衡量100%.窗口本身不算数.;)

要使某些东西完全伸展到窗口的100%,您有两种选择:

  1. 使用JavaScript
  2. 不要使用DOCTYPE.这不是一个好习惯,但是它将浏览器置于"怪癖模式",你可以在元素上执行height ="100%",它会将它们拉伸到窗口大小.请注意,您的页面的其余部分可能也必须更改以适应DOCTYPE更改.

更新:当我发布这个时,我不确定我是不是已经错了,但这肯定已经过时了.今天你可以在样式表中执行此操作:html, body { height: 100% }它实际上会延伸到整个视口.即使使用DOCTYPE.min-height: 100%也可能有用,具体取决于你的情况.

而且我也不建议任何人制作一个怪癖模式文档,因为它会导致比解决它们更令人头疼的问题.每个浏览器都有不同的怪癖模式,因此让您的页面在浏览器中保持一致性变得更加困难两个数量级.使用DOCTYPE.总是.最好是HTML5一个 - <!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;}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

一些注意事项 - second-row容器是必需的,因为bottom: 0并且由于right: 0某种原因不适用于iframe.与"被替换"元素有关的事情.但是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;}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

一些注意事项 - 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; }
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

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

  • @forgivenson-足够真实。在此答案的开头添加了注释。 (2认同)

小智 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;
Run Code Online (Sandbox Code Playgroud)

注意:ifm是iframe ID

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


小智 48

另一种方法是使用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;
    }
Run Code Online (Sandbox Code Playgroud)
   <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>
Run Code Online (Sandbox Code Playgroud)

  • 我注意到你还需要在iframe中添加`position:fixed`. (3认同)

duc*_*ucu 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>
Run Code Online (Sandbox Code Playgroud)


Jos*_*ier 36

以下是一些现代方法:



  • 方法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;
    }
    Run Code Online (Sandbox Code Playgroud)
    <div class="parent">
        <div class="banner"></div>
        <iframe></iframe>
    </div>
    Run Code Online (Sandbox Code Playgroud)

    由于这种方法支持较少1,我建议采用上述方法.

1 虽然它似乎在Chrome/FF中有效,但它在IE中不起作用(第一种方法适用于所有当前浏览器).

  • 工作和IMO这里提到的两个选项都是最好的方法.我更喜欢`flexbox`选项,因为使用`calc`你需要知道从'vh`中扣除的空间量.使用`flexbox`一个简单的`flex-grow:1`就可以了. (2认同)

小智 18

也许这已经得到了回答(上面的一些答案是"正确的"这样做的方式),但我想我也只是添加了我的解决方案.

我们的iFrame加载在div中,因此我需要其他东西然后window.height.看到我们的项目已经在很大程度上依赖于jQuery,我发现这是最优雅的解决方案:

$("iframe").height($("#middle").height());
Run Code Online (Sandbox Code Playgroud)

当然"#middle"是div的id.您需要做的唯一额外事情是在用户调整窗口大小时调用此大小更改.

$(window).resize(function() {
    $("iframe").height($("#middle").height());
});
Run Code Online (Sandbox Code Playgroud)


mon*_*ike 8

另一种选择是使用vh

<iframe src='/' style="display:block; border:none; height:100vh; width:100%;"></iframe>
Run Code Online (Sandbox Code Playgroud)


小智 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>
Run Code Online (Sandbox Code Playgroud)

我把它添加到头部.

请注意,我的iframe位于包含3行1列的表格的中间单元格内.


ARe*_*sal 6

没错,您正在显示一个相对于其容器(主体)具有 100% 高度的 iframe。

尝试这个:

<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>
Run Code Online (Sandbox Code Playgroud)

当然,将第二个div的高度更改为你想要的高度。

  • 可以使用 calc(100% - 30px) 而不是 90% (2认同)

小智 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;
Run Code Online (Sandbox Code Playgroud)