Html 使 iframe 适合容器剩余高度的 100%
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/325273/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Make Iframe to fit 100% of container's remaining height
提问by Darkthread
I want to design a web page with a banner and an iframe. I hope the iframe can fill all the remaining page height and be resized automatically as the browser is resizing. Is it possible to get it done without writing Javascript code, only with CSS?
我想设计一个带有横幅和 iframe 的网页。我希望 iframe 可以填充所有剩余的页面高度,并在浏览器调整大小时自动调整大小。是否可以不编写 Javascript 代码而仅使用 CSS 来完成它?
I tried set height:100%
on iframe, the result is quite close but the iframe tried to fill the whole page height, including the 30px
height of banner div element, so I got unneccessary vertical scrollbar. It's not perfect.
我尝试height:100%
在 iframe 上设置,结果非常接近,但 iframe 试图填充整个页面高度,包括30px
横幅 div 元素的高度,所以我得到了不必要的垂直滚动条。这并不完美。
Update Notes: Excuse me for not describing the question well, I tried CSS margin, padding attribute on DIV to occupy the whole remining height of a web page successfully, but the trick didn't work on iframe.
更新说明:请原谅我没有很好地描述问题,我尝试了 CSS 边距,DIV 上的填充属性成功占据了网页的整个重新挖掘高度,但该技巧在 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>
Any idea is appreciated.
任何想法表示赞赏。
采纳答案by Vilx-
Update in 2019
2019年更新
TL;DR:Today the best option is the last one in this answer - flexbox. Everything supports it nicely and has for years. Go for that and don't look back. The rest of this answer is left for historical reasons.
TL;DR:今天最好的选择是这个答案中的最后一个 - flexbox。一切都很好地支持它,并且多年来一直如此。去吧,不要回头。这个答案的其余部分是由于历史原因而留下的。
The trick is to understand what the 100% is taken of. Reading CSS specs can help you there.
诀窍是了解 100% 是什么。阅读 CSS 规范可以帮助你。
To make a long story short - there is such a thing as "containing block" - which is not necessary the parent element. Simply said, it is the first element up the hierarchy that has position:relative or position:absolute. Or the body element itself if there is nothing else. So, when you say "width: 100%", it checks the width of the "containing block" and sets the width of your element to the same size. If there was something else there, then you might get contents of a "containing block" that are larger than itself (thus "overflowing").
长话短说 - 有“包含块”这样的东西 - 这不是父元素所必需的。简单地说,它是层次结构中第一个具有 position:relative 或 position:absolute 的元素。或者身体元素本身,如果没有别的。因此,当您说“width: 100%”时,它会检查“包含块”的宽度并将元素的宽度设置为相同的大小。如果那里还有其他东西,那么您可能会得到比它本身大的“包含块”的内容(因此“溢出”)。
Height works the same way. With one exception. You can't get height to 100% of the browser window. The very top level element, against which 100% can be calculated, is the body (or html? not sure) element, and that stretches just enough to contain its contents. Specifying height:100% on it will have no effect, because it has no "parent element" against which to measure 100%. Window itself doesn't count. ;)
高度的工作方式相同。除了一个例外。您无法将高度设置为浏览器窗口的 100%。可以计算 100% 的最顶层元素是 body(或 html?不确定)元素,它的长度刚好足以包含其内容。指定 height:100% 不会有任何效果,因为它没有“父元素”来衡量 100%。窗口本身不算数。;)
To make something stretch exactly 100% of the window, you have two choices:
- Use JavaScript
- Don't use DOCTYPE. This is not a good practice, but it puts the browsers in "quirks mode", in which you can do height="100%" on elements and it will stretch them to the window size. Do note, that the rest of your page will probably have to be changed too to accommodate for the DOCTYPE changes.
要使某些内容完全拉伸窗口的 100%,您有两种选择:
- 使用 JavaScript
- 不要使用 DOCTYPE。这不是一个好的做法,但它会将浏览器置于“怪癖模式”,在这种模式下,您可以对元素执行 height="100%" 并将它们拉伸到窗口大小。请注意,页面的其余部分可能也必须更改以适应 DOCTYPE 更改。
Update:I'm not sure if I wasn't wrong already when I posted this, but this certainly is outdated now. Today you can do this in your stylesheet: html, body { height: 100% }
and it will actually stretch to the whole of your viewport. Even with a DOCTYPE. min-height: 100%
could also be useful, depending on your situation.
更新:当我发布这个时,我不确定我是否已经错了,但这现在肯定已经过时了。今天你可以在你的样式表中做到这一点:html, body { height: 100% }
它实际上会延伸到你的整个视口。即使使用 DOCTYPE。min-height: 100%
也可能有用,具体取决于您的情况。
And I wouldn't advise anyone to make a quirks-mode documentanymore either, because it causes way more headaches than solves them. Every browser has a different quirks-mode, so getting your page to look consistently across browsers becomes two orders of magnitude more difficult. Use a DOCTYPE. Always. Preferably the HTML5 one - <!DOCTYPE html>
. It's easy to remember and works like a charm in all browsers, even the 10 years old ones.
而且我也不建议任何人再制作一个 quirks-mode 文档,因为它比解决问题更令人头疼。每个浏览器都有不同的怪癖模式,因此让您的页面在浏览器中保持一致变得困难两个数量级。使用 DOCTYPE。总是。最好是 HTML5 一个 - <!DOCTYPE html>
. 它很容易记住,并且在所有浏览器中都具有魅力,即使是 10 年前的浏览器也是如此。
The only exception is when you have to support something like IE5 or something. If you're there, then you're on your own anyway. Those ancient browsers are nothing like the browsers today, and little advice that is given here will help you with them. On the bright side, if you're there, you probably just have to support ONE kind of browser, which gets rid of the compatibility problems.
唯一的例外是当您必须支持 IE5 之类的东西时。如果你在那里,那么无论如何你都是靠自己的。那些古老的浏览器与今天的浏览器完全不同,这里提供的一些建议会对您有所帮助。从好的方面来说,如果你在那里,你可能只需要支持一种浏览器,它摆脱了兼容性问题。
Good luck!
祝你好运!
Update 2:Hey, it's been a long time! 6 years later, new options are on the scene. I just had a discussion in the comments below, here are more tricks for you that work in today's browsers.
更新 2:嘿,好久不见!6 年后,新的选择出现了。我刚刚在下面的评论中进行了讨论,这里有更多适用于当今浏览器的技巧。
Option 1- absolute positioning. Nice and clean for when you know the precise height of the first part.
选项 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>
Some notes - the second-row
container is needed because bottom: 0
and right: 0
doesn't work on iframes for some reason. Something to do with in being a "replaced" element. But width: 100%
and height: 100%
works just fine. display: block
is needed because it's an inline
element by default and whitespace starts creating weird overflows otherwise.
一些注意事项-在second-row
需要的容器,因为bottom: 0
并right: 0
没有在内部框架出于某种原因的工作。与成为“被替换”元素有关。但是width: 100%
,height: 100%
工作得很好。display: block
是需要的,因为inline
默认情况下它是一个元素,否则空白会开始产生奇怪的溢出。
Option 2- tables. Works when you don't know the height of the first part. You can use either actual <table>
tags or do it the fancy way with display: table
. I'll go for the latter because it seems to be in fashion these days.
选项 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>
Some notes - the overflow: auto
makes sure that the row always includes all of its contents. Otherwise floating elements can sometimes overflow. The height: 100%
on the second row makes sure it expands as much as it can squeezing the first row as small as it gets.
一些注意事项 -overflow: auto
确保该行始终包含其所有内容。否则浮动元素有时会溢出。在height: 100%
第二行确保它扩展一样,因为它可以挤压第一排的小,因为它得到。
Option 3- flexbox. The cleanest one of them all, but with a less than stellar browser support. IE10 will need -ms-
prefixes for the flexbox properties, and anything less will not support it at all.
选项 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>
Some notes - the overflow: hidden
is because the iframe still generates some sort of overflow even with display: block
in this case. It isn't visible in the fullscreen view or the snippet editor, but the small preview window gets an extra scrollbar. No idea what that is, iframes are weird.
一些注意事项 - 这overflow: hidden
是因为即使display: block
在这种情况下,iframe 仍然会产生某种溢出。它在全屏视图或代码段编辑器中不可见,但小预览窗口有一个额外的滚动条。不知道那是什么,iframe 很奇怪。
回答by MichAdel
We use a JavaScript to solve this problem; here is the source.
我们使用 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;
Note: ifm
is the iframe ID
注意:ifm
是iframe ID
pageY()
was created by John Resig (the author of jQuery)
pageY()
由 John Resig(jQuery 的作者)创建
回答by D1SoveR
Another way to do that would be to use the position: fixed;
on parent node.
If I am not mistaken, position: fixed;
ties the element to viewport, thus, once you give this node width: 100%;
and height: 100%;
properties, it will span over entire screen. From this point on, you can put <iframe>
tag inside it and span it over remaining space (both in width and in height) with simple width: 100%; height: 100%;
CSS instruction.
另一种方法是使用position: fixed;
父节点。
如果我没记错的话,position: fixed;
将元素绑定到视口,这样,一旦你给这个节点width: 100%;
和height: 100%;
属性,它就会跨越整个屏幕。从现在开始,您可以<iframe>
使用简单的width: 100%; height: 100%;
CSS 指令将标签放入其中并跨越剩余空间(宽度和高度)。
Example code
示例代码
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>
回答by Josh Crozier
Here are a few modern approaches:
以下是一些现代方法:
Approach 1 - Combination of viewport relative units/
calc()
.The expression
calc(100vh - 30px)
represents the remaining height. Where100vh
is the height of the browser and the usage ofcalc()
effectively displaces the height of the other element.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>
Support for
calc()
here; support for viewport relative units here.
方法 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>
Approach 2 - Flexbox approach
Set the
display
of the common parent element toflex
, along withflex-direction: column
(assuming you want the elements to stack on top of each other). Then setflex-grow: 1
on the childiframe
element in order for it to fill the remaining space.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>
Since this approach has less support1, I'd suggest going with the aforementioned approach.
方法 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,我建议采用上述方法。
1Though it seems to work in Chrome/FF, it doesn't work in IE (the first method works in all current browsers).
1虽然它似乎在 Chrome/FF 中工作,但它在 IE 中不起作用(第一种方法适用于所有当前浏览器)。
回答by ducu
You can do it with DOCTYPE
, but you have to use table
. Check this out:
您可以使用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>
回答by Tim Geerts
Maybe this has been answered already (a few answers above are "correct" ways of doing this), but I thought I'd just add my solution as well.
也许这已经得到了回答(上面的一些答案是这样做的“正确”方法),但我想我也应该添加我的解决方案。
Our iFrame is loaded within a div, hence I needed something else then window.height. And seeing our project already relies heavily on jQuery, I find this to be the most elegant solution:
我们的 iFrame 是在一个 div 中加载的,因此我需要别的东西,然后是 window.height。看到我们的项目已经严重依赖 jQuery,我发现这是最优雅的解决方案:
$("iframe").height($("#middle").height());
Where of course "#middle" is the id of the div. The only extra thing you'll need to do is recall this size change whenever the user resizes the window.
当然“#middle”是div的id。您唯一需要做的额外事情就是在用户调整窗口大小时调用此大小更改。
$(window).resize(function() {
$("iframe").height($("#middle").height());
});
回答by Danut Milea
Here's what I did. I had the same problem and ended up searching the web for resources for hours.
这就是我所做的。我遇到了同样的问题,最终在网上搜索了几个小时的资源。
<style type="text/css">
html, body, div, iframe { margin:0; padding:0; height:100%; }
iframe { position:fixed; display:block; width:100%; border:none; }
</style>
I added this to the head section.
我将此添加到头部部分。
Please note that my iframe is located inside the middle cell of a table that has 3 rows and 1 column.
请注意,我的 iframe 位于具有 3 行和 1 列的表格的中间单元格内。
回答by asimrafi
MichAdel code works for me but I made some minor modification to get it work properly.
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;
回答by sree
try the following:
尝试以下操作:
<iframe name="" src="" width="100%" style="height: 100em"/>
it worked for me
它对我有用
回答by ARemesal
It's right, you are showing an iframe with 100% height respect to its container: the body.
没错,您正在显示一个 iframe,其高度相对于其容器:主体。
Try this:
尝试这个:
<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>
Of course, change the height of the second div to the height you want.
当然,把第二个div的高度改成你想要的高度。