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

新手上路,请多包涵

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

我尝试在 iframe 上设置 height:100% ,结果非常接近,但 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>

原文由 Darkthread 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.7k
2 个回答

2019年更新

TL;DR: 今天最好的选择是 - flexbox 。一切都很好地支持它并且已经使用了多年。去吧,不要回头。这是 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>

这个答案的其余部分是出于学习和历史原因。


诀窍是了解 100% 的内容。阅读 CSS 规范可以帮助你。

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

高度以同样的方式工作。除了一个例外。您无法将高度设置为浏览器窗口的 100%。可以计算 100% 的最顶层元素是 body(或 html?不确定)元素,它的长度刚好足以包含其内容。在其上指定 height:100% 将没有任何效果,因为它没有用于测量 100% 的“父元素”。窗口本身不算数。 ;)

要使某些东西恰好 100% 地拉伸窗口,您有两种选择:

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

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

而且我 也不建议任何人再制作怪癖模式文档,因为它引起的麻烦远比解决问题的方法多。每个浏览器都有不同的怪癖模式,因此让您的页面在浏览器中看起来一致变得更加困难两个数量级。使用文档类型。总是。最好是 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;}
 <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 由于某种原因在 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;}
 <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 - 其中最干净的一个。

 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 很奇怪。

原文由 Vilx- 发布,翻译遵循 CC BY-SA 4.0 许可协议

我们使用 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 的作者)创建

原文由 MichAdel 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题