【问题标题】:CSS vh units inside an iframeiframe 内的 CSS vh 单元
【发布时间】:2015-12-03 03:15:15
【问题描述】:

我正在尝试在 iframe 中使用 CSS vh 单位。我发现它们以某种方式缩放到 iframe 的大小。换句话说,100vh 不是窗口高度。它设置为 iframe 的高度。

这看起来对吗?

有解决办法吗?

【问题讨论】:

  • 为此使用 javascript。查看window.innerWidthwindow.innerHeight
  • iframe 是否在同一个域中?
  • 你能为我们做一个 jsfiddle 吗?
  • 同一个域。看来我需要使用 JS 或将 vh 小数部分设置为 iframe 的总高度。无法制作小提琴自动取款机。 @www139
  • FWIW:起初我根本无法让 vw、vh 工作。原来我复制了一个旧的 iframe 示例,它设置了 iframe 标签的 widthheight 属性。例如<iframe ... width: "320" height: "200" .../>删除那些 - vw 和 vh 在那里不起作用 - 并使用 CSS 样式。例如。如果做 inline CSS:<iframe ... style="width: 100%; height: 80vh" .../>.

标签: css iframe


【解决方案1】:

我知道这是一个老问题,但随着人们转向vh 单元,这个问题将变得更加普遍。

为了澄清,这里有一个问题的例子。我们有一个加载 iframe 的 HTML 文件:

<!DOCTYPE html>
<html>
<head></head>
<style>
iframe {
    height: 50vh;
    width: 100%;
}
</style>
<body>
    <iframe src="iframe.html"/>
</body>
</html>

还有它的iframe

<!DOCTYPE html>
<html>
<head></head>
<style>
div {
    height: 50vh;
    width: 100%;
    background: blue;
}
</style>
<body>
    <div></div>
</body>
</html>

这里要注意的重要一点是iframeiframe's div 元素都被指定为具有50vh 的高度。预期的行为可能是 iframe 尊重父上下文的视口高度或宽度。相反,结果如下所示:

也就是说,蓝色元素的高度约为浏览器窗口的 25%,而不是预期的 50%(iframe 的 100%)。尽管我们可能希望iframe 尊重其父级的视口,但这个示例很好地说明了这可能是多么不直观,尽管它肯定会使v* 单元对于iframe'd 的内容更有价值. 问题与如何确定视口高度有关。

来自the spec

视口百分比长度与初始包含块的大小有关。当初始包含块的高度或宽度发生变化时,它们会相应地缩放。

iframe 和浏览器窗口都可以是initial containing block,因为它们都是有效的视口。视口不限于浏览器窗口,而是定义为屏幕上用户查阅文档的窗口或其他查看区域

iframe 在插入文档时会创建一个nested browsing context,因此是它自己的视口。

所以是的,这是预期的行为 - 不幸的是,没有纯 CSS 解决方法 - 然而,www139 提供了一个如何使用 JavaScript 完成此操作的示例。当使用v* 单位控制许多元素的大小时,问题就开始了。

【讨论】:

  • 我希望在 safari 中实现这种确切的行为,但 safari 喜欢使用 vh 作为主浏览器视口,而不是 iframe 的高度 :( 所以与你有完全相反的问题 :(
  • @Simon_Weaver 我在 Safari 11.1 中得到了相同的结果。我无法想象它的工作方式存在很大差异,因为它是规范的一部分。你确定同样的机制对你有用吗?您是否在浏览器中尝试过上述最低限度完整的示例?
  • 看来 Safari 对 iframe 非常挑剔。高度设置为 100vh 的元素显示为内容的完整高度,而不是视口高度。固定位置元素完全中断滚动。此外,我相信同域 iframe 的行为也略有不同。所以也许这些东西有影响。我试图创建一个 iframe 来在 ipad 上托管我的网站,以模拟不同的屏幕尺寸。我放弃了,因为看起来 iOS 只是不希望你这样做。最后,我找到了一个应用程序“检查”,它可以在本地执行此操作,甚至在 iOS 上为我提供了一个控制台。
  • 在你的测试中你可以滚动窗口。显然,为了测试一个网站,我需要滚动 - 所以这可能是区别。当我运行 testiphone.com(100vh 填充视口)时,我能够看到我所追求的“正确”行为,但我无法滚动它。我希望 iframe 像一个完全独立的浏览器一样工作,但显然这不会发生。幸运的是,我发现的 ipad 应用运行良好。
【解决方案2】:

这是一个很好的问题。遗憾的是,我无法在 CSS 中找到解决方案,但我已经能够在 JavaScript 中找到解决方案,我认为这是您目前最好的选择。请记住,框架必须在同一个域中才能正常工作。

希望这会有所帮助。如果这个答案需要改进,请在下面评论:-)

理论上的解决方案(由于框架来源问题,因此无法在此处使用):

window.addEventListener('load',function(){
    initializeV();
    function initializeV(){
            //1% of the parent viewport width (same as 1vw):
            var vw = window.parent.innerWidth/100;
            //1% of the viewport height (same as 1vh):
            var vh = window.parent.innerHeight/100;

            //assign width and height to your v unit elements here
    }

    window.parent.addEventListener('resize',function(){
          //when the browser window is resized; recalculate
          initializeV();
    });
});

编辑(2018 年 12 月):在 cmets 中,我被要求提供一个示例。我不能做一个确切的例子,因为 Stackoverflow 上的 codepens 加载在与页面不同的帧源上。但是,我可以模仿效果。实际应用请参考上面的代码sn-p。这个 sn-p 只是为了说明它是如何工作的。

实际应用。使用上面解释的概念,但没有框架参考。

window.addEventListener('load',function(){
        initializeV();
        function initializeV(){
                //note: I can't use window.parent becuase the code snippet loads on a different frame than the parent page. See the other snippet for a practical example. This snippet is meant to merely illustrate the effect.
                //1% of the parent viewport width (same as 1vw):
            	var vw = window.innerWidth/100;
                //1% of the viewport height (same as 1vh):
            	var vh = window.innerHeight/100;
        
              //this is where the magic happens. Simply set width/height/whatever to a multiple of vw/vh and add 'px'. Dimensions must be in pixels since the vw/vh measurement is based on pixels.
              document.getElementById('test').style.width = 30*vw+'px';
              document.getElementById('test').style.height = 50*vh+'px';
                //assign width and height to your v unit elements here
        }
        
        window.addEventListener('resize',function(){
              //when the browser window is resized; recalculate
              initializeV();
        });
    });
#test{
background:red;
}
&lt;div id="test"&gt;&lt;/div&gt;

【讨论】:

  • @JamieCounsell “//在此处为您的 v 单元元素分配宽度和高度”是什么意思?我怎么做?你能举个例子吗?谢谢
  • @SamGurdus 这是用 JavaScript 设置 CSS 属性的地方。例如,document.getElementById("test").style.width = 10*vw+'px'; 会将元素 #test 的宽度设置为视口宽度的 10%(或 10vw)。
  • 我在 iframe 中有另一个 iframe,我认为这会破坏它。这是主 iframe 的代码。 jsfiddle.net/samgurdus/o3vkhp5o
  • 愿意解释反对意见吗?您认为哪些方面可以改进?
  • 我认为任何反对意见都是因为您没有对计算值做任何有用的事情。无论如何,vh 的全部意义在于在 css 中使用它。你只是在调用一个不能用作 vh 的变量 vh。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-06-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-11
  • 2014-12-28
相关资源
最近更新 更多