乐闻世界logo
搜索文章和话题

Iframe 如何适应容器的剩余高度?

7 个月前提问
3 个月前修改
浏览次数199

7个答案

1
2
3
4
5
6
7

在开发Web应用时,经常需要让iframe适应其容器的剩余高度。这通常是为了确保iframe内的内容能够良好地显示,而不需要额外的滚动条或空白区域。解决这一问题主要有以下几种方法:

方法一:CSS Flexbox

使用CSS的Flexbox布局可以非常方便地实现iframe自适应高度。假设你有一个父容器,里面包含一些其他元素和一个iframe,你可以通过设置父容器为flex布局,并让iframe占据所有剩余空间。

HTML结构示例:

html
<div class="container"> <div class="header"> <!-- 其他内容 --> </div> <iframe class="flexible-iframe" src="example.html"></iframe> </div>

CSS样式:

css
.container { display: flex; flex-direction: column; height: 100vh; /* 假设你希望整体容器填满一个视口的高度 */ } .header { /* 高度根据内容自适应 */ } .flexible-iframe { flex: 1; /* 占据所有剩余空间 */ }

方法二:JavaScript动态调整

如果因为某些原因,CSS方法不适用于你的情况,你可以使用JavaScript来动态调整iframe的高度。这种方法可以在iframe内容变化时动态调整高度。

示例代码:

javascript
window.addEventListener("load", function() { var iframe = document.querySelector("iframe"); var containerHeight = document.querySelector(".container").clientHeight; var otherContentHeight = document.querySelector(".header").clientHeight; iframe.style.height = containerHeight - otherContentHeight + "px"; });

方法三:使用CSS的vh单位

如果iframe位于页面的较低位置,并且上面的元素高度固定,你也可以直接使用视口高度(vh)单位来设置iframe的高度。

示例代码:

css
.header { height: 50px; /* 假设头部高度为50px */ } .flexible-iframe { height: calc(100vh - 50px); /* 剩余的视口高度 */ }

实际应用示例

在一个实际项目中,我们需要在一个管理系统的仪表板中嵌入一个报告系统的iframe。我们使用了Flexbox方法,因为它提供了最灵活的布局解决方案,并且能够自动适应我们界面中其他动态变化的部分,例如可折叠的侧边栏。通过设置flex: 1,iframe能够始终占据除顶部导航栏和侧边栏外的所有可用空间,无论视口大小如何变化。

以上就是几种使iframe适应其容器剩余高度的方法。根据不同的项目需求和布局特点,可以选择最合适的方法来实现。

2024年6月29日 12:07 回复

2019年更新

**TL;DR:**今天最好的选择是 - flexbox。一切都很好地支持它并且已经存在了很多年。努力去做,不要回头。下面是 Flexbox 的代码示例:

shell
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 - 绝对定位。当您知道第一部分的精确高度时,效果会很好而且干净。

shell
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: 0,它right: 0不能在 iframe 上工作。与“被替换”元素有关。但是width: 100%并且height: 100%工作得很好。display: block是必需的,因为inline默认情况下它是一个元素,否则空格会开始产生奇怪的溢出。

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

shell
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 - 其中最干净的一个。

shell
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是因为即使在这种情况下,iframe 仍然会产生某种溢出display: block。它在全屏视图或代码片段编辑器中不可见,但小预览窗口有一个额外的滚动条。不知道那是什么,iframe 很奇怪。

2024年6月29日 12:07 回复

我们使用JavaScript来解决这个问s


shell
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 的作者)创建

2024年6月29日 12:07 回复

另一种方法是使用 position: fixed;父节点。 如果我没有记错的话,position: fixed;将元素绑定到视口,因此,一旦你给出这个节点 width: 100%;height: 100%;属性,它将跨越整个屏幕。从现在开始,您可以将 <iframe>标签放入其中,并使用简单的 CSS 指令将其跨越剩余空间(宽度和高度)width: 100%; height: 100%;

示例代码


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

展开片段

2024年6月29日 12:07 回复

以下是一些现代方法:


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

    该表达式calc(100vh - 30px)表示剩余高度。其中100vh是浏览器的高度,并且使用calc()有效地取代了其他元素的高度。

    示例在这里

    shell
    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: 1iframe元素以使其填充剩余空间。

    shell
    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 中不起作用(第一种方法适用于当前所有浏览器)。

2024年6月29日 12:07 回复

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

shell
<!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>
2024年6月29日 12:07 回复

为iframe设置以填充其容器剩余高度的 100%,我们可以采取以下几个步骤:

  1. 确保父容器的高度正确设置: 首先,需要确保iframe的父容器有确定的高度。如果父容器没有设定高度,iframe也就无法根据百分比来设置自己的高度。比如,我们可以为父容器设置一个固定的高度,或者设置为屏幕高度的百分比。
  2. CSS样式: 我们可以使用CSS来确保iframe可以自适应其父容器的剩余高度。以下是一个CSS样式示例,其中 .container是父容器的类名,而 .responsive-iframe是iframe的类名。
css
.container { position: relative; /* 或者使用flex布局也可以 */ height: 500px; /* 例如固定高度或者使用vh单位 */ } .responsive-iframe { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
  1. HTML结构: 确保iframe位于设定了高度的父容器内部,并且应用了相应的CSS样式类。
html
<div class="container"> <iframe src="your-frame-source.html" frameborder="0" class="responsive-iframe"></iframe> </div>
  1. 考虑容器内其他元素: 如果容器内还有其他元素,那么需要计算这些元素所占的空间,以便iframe可以填满剩下的空间。这可能需要动态计算其他元素的高度并相应地调整iframe的高度。
  2. 使用JavaScript进行动态调整: 如果需要动态地调整iframe的大小以适应不同的屏幕尺寸或内容变化,我们可以使用JavaScript来监听窗口尺寸变化事件(resize事件),并动态地计算并设置iframe的高度。
javascript
window.addEventListener('resize', function() { var containerHeight = document.querySelector('.container').clientHeight; var iframe = document.querySelector('.responsive-iframe'); iframe.style.height = containerHeight + 'px'; });

以上就是设置iframe以填满其父容器剩余高度的方法。

2024年6月29日 12:07 回复

你的答案