Flexbox 和 vh 高度单位在 IE11 中不兼容吗?

Posted

技术标签:

【中文标题】Flexbox 和 vh 高度单位在 IE11 中不兼容吗?【英文标题】:Are Flexbox and vh height units not compatible in IE11? 【发布时间】:2014-09-30 09:59:02 【问题描述】:

我正在尝试使用基于 flexbox 的布局来为我的页面获取粘性页脚。这在 Chrome 和 Firefox 中运行良好,但在 IE11 中,页脚位于我的主要内容之后。换句话说,主要内容不会被拉伸以填满所有可用空间。

body 
    border: red 1px solid;
    min-height: 100vh;
    display: -ms-flexbox;
    display: -webkit-flex;
    display: flex;
    -ms-flex-direction: column;
    -webkit-flex-direction: column;
    flex-direction: column;

header, footer  
    background: #dd55dd;

main 
    background: #87ccfc;
    -ms-flex: 1 0 auto;
    -webkit-flex: 1 0 auto;
    flex: 1 0 auto;
<body>
    <header role="banner"><h1> .. </h1></header>
    <main role="main">
        <p>.....</p>
    </main>
    <footer>...</footer>
</body>

当容器高度单位在 IE 中以 vh 测量时,如何让主要元素在 flex 布局中拉伸?我想看看这种行为是否是 IE 实现 flexbox 规范的方式中的错误的结果,但我在其他地方找不到任何提及这个问题的地方。

JSFiddle Demo

【问题讨论】:

【参考方案1】:

我昨天遇到了同样的错误,我自己也无法解决。不幸的是,目前似乎无能为力,因为它是 IE 错误,大约一年前已向微软开发人员报告,这里:

https://connect.microsoft.com/IE/feedback/details/802625/min-height-and-flexbox-flex-direction-column-dont-work-together-in-ie-10-11-preview

【讨论】:

【参考方案2】:

问题不在于vh 单位,而是min-height

我找到了一个半工作的纯 CSS 解决方案:

min-height: 100vh;
height: 100px;

额外的height 将使IE 能够垂直填充屏幕,即使内容不够高。缺点是如果内容比视口长,IE 将不再包裹内容。


由于这还不够,我在 JS 中做了一个解决方案:

检测

此函数测试错误:true 表示它有错误。

function hasBug () 
    // inner should fill outer
    // if inner's height is 0, the browser has the bug

    // set up
    var outer = document.createElement('div');
    var inner = document.createElement('div');
    outer.setAttribute('style', 'display:-ms-flexbox; display:flex; min-height:100vh;');
    outer.appendChild(inner);
    (document.body || document.documentElement).appendChild(outer);

    // test
    var bug = !inner.offsetHeight;

    // remove setup
    outer.parentNode.removeChild(outer);

    return bug;

修复

修复包括手动设置px中元素的height

function fixElementHeight (el) 
    // reset any previously set height
    el.style.height = 'auto'; 

    // get el height (the one set via min-height in vh)
    var height = el.offsetHeight; 

    // manually set it in pixels
    el.style.height = height + 'px'; 

元素的高度将设置为其内容的高度。 height 在 IE 中用作辅助 min-height,使用在纯 CSS 解决方案中观察到的行为。

用法

一旦定义了这两个函数,就可以这样设置:

if(hasBug()) 
    // fix the element now
    fixElementHeight(el);

    // update the height on resize
    window.addEventListener('resize', function () 
        fixElementHeight(el);
    );

演示

function hasBug () 
    // inner should fill outer
    // if inner's height is 0, the browser has the bug

    // set up
    var outer = document.createElement('div');
    var inner = document.createElement('div');
    outer.setAttribute('style', 'display:-ms-flexbox; display:flex; min-height:100vh;');
    outer.appendChild(inner);
    (document.body || document.documentElement).appendChild(outer);

    // test
    var bug = !inner.offsetHeight;

    // remove setup
    outer.parentNode.removeChild(outer);

    return bug;


function fixElementHeight (el) 
    // reset any previously set height
    el.style.height = 'auto'; 

    // get el height (the one set via min-height in vh)
    var height = el.offsetHeight; 

    // manually set it in pixels
    el.style.height = height + 'px'; 


var output = document.getElementById('output');
output.innerhtml = hasBug()?'Browser is buggy':'Browser works correctly';


var el = document.getElementById('flex');

if(hasBug()) 
  // fix the element now
  fixElementHeight(el);

  // update the height on resize
  window.addEventListener('resize', function () 
    fixElementHeight(el);
  );
.half-screen 
  display:-ms-flexbox;
  display: flex;
  min-height: 50vh;

  padding: 10px;
  background: #97cef0;



.content 
  padding: 10px;
  background: #b5daf0;
The inner box should fill the outer box vertically, even if the browser is buggy.
<div class="half-screen" id="flex">
  <div class="content" id="output">
    Text
  </div>
</div>

【讨论】:

以及height:100px 我发现将overflow-y:auto 添加到我的main 内容区域在所有浏览器中都可以正常工作。【参考方案3】:

通常这会有所帮助:

html, body 
   height: 100%;

.. 你不必使用vh 单位。

完整样本:

* 
  margin: 0;

html,
body 
  height: 100%;

body 
  border: red 1px solid;
  display: -ms-flexbox;
  display: -webkit-flex;
  display: flex;
  -ms-flex-direction: column;
  -webkit-flex-direction: column;
  flex-direction: column;

header,
footer 
  background: #dd55dd;

main 
  background: #87ccfc;
  -ms-flex: 1;
  -webkit-flex: 1;
  flex: 1;
  overflow-y: scroll;
  -webkit-overflow-scrolling: touch;
<header>
  <h1>Herons - How they plan to eat your eyes!</h1>
</header>
<main>
  Herons are foul and devious birds.
</main>
<footer>
  <small>© 2014 Institute for the prevention of Herons</small>
</footer>

【讨论】:

你没有理解需求。 body 至少应该占据整个屏幕,但可以占据更多。这是min-height 的目的,这在 IE 中是错误的。【参考方案4】:

我发现让粘性页脚在 IE11 中工作的技巧是确保 flex-basis100% 甚至是 100vh。请参阅下面的示例或您可以在 IE11 中测试的 live Codepen example。

html 
  display: flex;
  flex-direction: column;


body 
  display: flex;
  flex-direction: column;
  flex-grow: 1;
  flex-basis: 100%;
  min-height: 100vh;


header 
  padding: 32px;
  background-color: seagreen;


main 
  flex-grow: 1;
  padding: 32px;
  background-color: rgba(0, 0, 0, 0.05);


footer 
  padding: 32px;
  background-color: coral;
<header>
  Header
</header>
<main>
  <p>I will not skateboard in the halls.</p>
  <p>I will not skateboard in the halls.</p>
  <p>I will not skateboard in the halls.</p>
  <p>I will not skateboard in the halls.</p>
  <p>I will not skateboard in the halls.</p>
  <p>I will not skateboard in the halls.</p>
  <p>I will not skateboard in the halls.</p>
  <p>I will not skateboard in the halls.</p>
  <p>I will not skateboard in the halls.</p>
  <p>I will not skateboard in the halls.</p>
  <p>I will not skateboard in the halls.</p>
</main>
<footer>
  Footer
</footer>

【讨论】:

感谢您为我指明正确的方向,@souporserious。然而,实际上对我有用的只是将display: flexflex-direction: column 行添加到html CSS 元素。就此而言,将 flex-basis: 100% 添加到 body CSS 元素对 IE11 或现代浏览器没有任何影响。

以上是关于Flexbox 和 vh 高度单位在 IE11 中不兼容吗?的主要内容,如果未能解决你的问题,请参考以下文章

Safari Flexbox,可滚动,100vh 问题

2D变换过渡不适用于IE11中的VW和VH单元

flexbox中的图像高度在IE中不起作用

flexbox 列和 IE

IE 11 的 Flexbox 问题

等效于 fr(分数)单位的 Flexbox