HTML5 Doctype与iframe

4
当在HTML5 doctype中包含一个全高度/宽度的iframe时,会添加一个无法删除的底部边框。这会为页面添加滚动条以适应边框。不幸的是,我受到以下限制:
  • 需要使用iframe
  • iframe位于占据整个屏幕的固定位置容器内部
  • html和body具有overflow hidden
  • 需要HTML5 doctype(删除doctype或切换到旧的doctype将修复滚动条问题)
  • 需要保持#container上的overflow-y:auto和-webkit-overflow-scrolling:touch,因为iOS否则无法滚动框架(或好像不能使其滚动)。
我有一个plunker here表现出相同的情况。从中删除html5 doctype显示它将解决该问题(但这不是可行的解决方案)。
是否有任何CSS或属性可以删除底部边框并删除外部(不必要的)滚动条?

html {
    box-sizing: border-box;
}

*, *:before, *:after {
    box-sizing: inherit;
}

html, body {
    height: 100%;
    margin: 0;
    padding: 0;
    overflow: hidden;
}

#container {
    position:fixed;
    top: 0;
    left: 0;
    height: 100%;
    width: 100%;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
}

#foo {
    height: 100%;
    width: 100%;
}
<!DOCTYPE html>
<html>

  <body>
    <div id="container">
      <iframe id="foo" frameborder="0" marginwidth="0" marginheight="0"
      src="//www.iana.org/domains/reserved"></iframe>
    </div>
  </body>

</html>


请在 iPhone 上查看并测试我的解决方案。我很好奇它是否成功,但不太好奇去购买 iPhone。:P - zer00ne
我没测试,因为在桌面浏览器中查看时有两个滚动条。 - Patrick
已更新 http://plnkr.co/edit/QkF05lhU3dH3qhn7JQ7N?p=preview - zer00ne
3个回答

3

“底部边框”不是边框,而是内联元素的空间(iframe是内联元素),所以解决方法就是消除那个“空间”。

以下是三种适用于“foo”的方法:

  • display: block
  • position: absolute
  • margin-bottom: -4px;

注意:在iOS上,display: block看起来并不是很有效。

html {
    box-sizing: border-box;
}

*, *:before, *:after {
    box-sizing: inherit;
}

html, body {
    height: 100%;
    margin: 0;
    padding: 0;
    overflow: hidden;
}

#container {
    position:fixed;
    top: 0;
    left: 0;
    height: 100%;
    width: 100%;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
}

#foo {
    display: block;
    height: 100%;
    width: 100%;
}
<!DOCTYPE html>
<html>

  <body>
    <div id="container">
      <iframe id="foo" frameborder="0" marginwidth="0" marginheight="0"
      src="//www.iana.org/domains/reserved"></iframe>
    </div>
  </body>

</html>


我对这个解决方案感到兴奋...由于某种原因,这也会在 iPhone 上破坏滚动 :( - Patrick
使用 margin-bottom: -4px 也会出现问题吗?请查看我的更新。 - Asons
我对神奇的4px数字感到害怕。有没有任何规范中说内联元素的边距是这个值?我尝试在#foo上设置position: absolute,初步测试似乎可以解决问题(虽然我更喜欢块级元素)。 - Patrick
负边距被广泛应用于解决行内元素之间的空隙问题。您可以在这里了解更多关于这个“空隙问题”的信息:https://css-tricks.com/fighting-the-space-between-inline-block-elements/ - Asons
请告诉我它在iPhone上的表现如何(哪种方法最好,你选择了什么),我会将其作为我的答案的注释添加进去。 - Asons
理想情况下,display:block应该可以工作,但是滚动被破坏了。在一个iOS设备上的初始尝试表明,position:absolute是有效的。我还考虑使用height:calc(100% - 4px)在#foo上做类似的事情,但是硬编码的4似乎是一种hack(即使最初的测试似乎显示4是当前浏览器中使用的正确值)。我接受这个答案,因为我固执地认为这是内联元素的边框而不是一些间距。 - Patrick

2

默认情况下,对于未使用display: block的元素,似乎存在额外的边距。

以下纯CSS解决方案似乎适用于移动Safari和Chrome桌面版。

.demo-iframe-holder {
  position: fixed; 
  right: 0; 
  bottom: 0; 
  left: 0;
  top: 0;
  -webkit-overflow-scrolling: touch;
  overflow-y: scroll;
}

.demo-iframe-holder iframe {
  display: block;
  height: 100%;
  width: 100%;
  margin: 0;
  border: 0;
}
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
    </head>

  <body>
    
    <div class="demo-iframe-holder">
        <iframe frameborder="0" scrolling="yes" src="//www.iana.org/domains/reserved"></iframe>
    </div>
    
  </body>

</html>


这确实可以消除桌面上的滚动条,但是在iPhone上无法滚动,例如(在iOS中编辑并打开plunker,转至横屏模式,然后查看滚动不起作用)。 - Patrick
我已经修改了答案,使其适用于移动版Safari,并在我的iPhone 6上进行了测试。它似乎按照您的意图正常工作。 - Tina
在桌面上使用Chrome(和其他桌面浏览器),由于overflow-y: auto,会出现双滚动条的情况...您更新的答案与我原始帖子中没有任何区别...为了澄清一下,我的帖子目前在iPhone上可以正常工作 - 希望能够让它在桌面浏览器上正常工作,并且不会影响到手机上的滚动。 - Patrick
我修改了我的回答以提供解决方案。也许它不是最优雅的,因为它使用了JavaScript,但似乎它可以工作。 - Tina
用点赞奖励您的时间 - 寻找仅使用CSS的解决方案,我认为我们与LGSon很接近。 - Patrick

0
看起来我来晚了...我的解决方案在任何移动设备上都没有经过测试。所有更改都已在CSS(style.css)中进行注释,并且标记只有一个修改:scrolling="no"iframe#foo

PLUNKER

HTML

<!doctype html>
<html>

  <head>
    <link rel="stylesheet" href="style.css">
    <script src="script.js"></script>
  </head>

  <body>
    <div id="container">
      <iframe id="foo" frameborder="0" scrolling='no' marginwidth="0" marginheight="0"
      src="//www.iana.org/domains/reserved"></iframe>
    </div>
  </body>

</html>

CSS

/* S.O. 33571717 */
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/

/* NOTE: This style is contingent upon the iframe #foo... */
/* having the attribute: scrolling="no" */

html {
  box-sizing: border-box;
}

*,
*:before,
*:after {
  box-sizing: inherit;
}

html,
body {
  /* If html is 100%... what is html's parent? 100% of nothing? */
  /* Having +100% unit higher than max will extend overflow: auto */

  /* Using vh and vw units to ensure accurate viewport dimensions... */
  /* see http://goo.gl/yQZX8v */

  height: calc(100vh + 100%);
  /* set as vh instead of % */
  width: 100vw;
  /* set as vw instead of % */
  margin: 0;
  padding: 0;
  /* split overflow's axis */
  overflow-y: auto;
  overflow-x: hidden;
}

#container {
  /* changed from fixed */
  position: relative;
  top: 0;
  left: 0;
  height: 100%;
  width: 100%;
  /* split overflow's axis */
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
}

#foo {
  height: 100%;
  width: 100%;
  /* added #foo to 'flow' of #container */
  position: absolute;
  /* #foo is stretched to every corner of #container */
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  /* split overflow's axis */
  overflow-y: auto;
  overflow-x: hidden;
}

/* THIS HAS NOT BEEN TESTED ON ANY MOBILE DEVICES */

/* This media query is DEVICE specific to an iPhone 6+ */

/* NOTE: Use media queries for landscape and portrait mode... */
/* the properties are reversed basically */

/* iPhones do not follow a simple logic for media query dimensions... */
/* see http://stephen.io/mediaqueries/ */

@media only screen and (min-device-width: 414px) and (max-device-width: 736px) and (orientation : landscape){
  html, body {
    overflow-y: hidden;
    overflow-x: auto;
    height: 100vh;
    width: calc(100vw + 100%);
  }
  #container {
    overflow-x: auto;
  }
  #foo {
    overflow-y: hidden;
    overflow-x: auto;
  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接