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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25177791/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 02:26:41  来源:igfitidea点击:

Are Flexbox and vh height units not compatible in IE11?

htmlcssflexboxinternet-explorer-11viewport-units

提问by Ritchie Allen

I'm trying to use a flexbox-based layout to get a sticky footer for my page. This works well in Chrome and Firefox, but in IE11 the footer sits just after my main content. In other words, the main content isn't stretched to fill all of the available space.

我正在尝试使用基于 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>

How can I get the main element to stretch in a flex layout when the containers height units are measured in vhin IE? I was looking to see if this behaviour is the result of a bug in the way IE implements the flexbox specs, but I couldn't find any mention of this problem elsewhere.

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

JSFiddle Demo

JSFiddle 演示

回答by fregante

The issue isn't vhunits but min-height

问题不是vh单位而是min-height

I found a semi-working CSS-only solution:

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

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

The extra heightwill enable IE to fill the screen vertically even if the content is not tall enough. The drawback is that IE will no longer wrap the content if it's longer than the viewport.

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



Since this is not enough I made a solution in JS:

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

Detection

检测

This function tests the bug: truemeans it's buggy.

此功能测试错误: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;
}

Fix

使固定

The fix consists of manually setting the heightof the element in px

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

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'; 
}

The element's height will be set to exactly the height of its content. heightis used as a secondary min-heightin IE, using the behavior observed in the CSS-only solution.

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

Usage

用法

Once those two functions are defined, set it up this way:

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

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

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

Demo

演示

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>

回答by Indy

I came across this same bug yesterday and couldn't solve it by myself either. Unfortunately, seems nothing can be done about it, at the moment, because it's IE bug, which have been reported to the Microsoft developers almost a year ago, here:

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

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

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

回答by souporserious

The trick I've found to getting sticky footers working in IE11 is to make sure flex-basisis 100%or even 100vh. Please see an example below or a live Codepen examplethat you can test in IE11.

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

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>

回答by Veiko J??ger

Usually this helps:

通常这有助于:

html, body {
   height: 100%;
}

.. and you don't have to use vhunits.

.. 你不必使用vh单位。

Full sample:

完整样本:

* {
  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>