在IE11中,不会从正常流程中删除绝对定位的弹性项目

时间:2015-10-07 11:30:21

标签: html css css3 flexbox internet-explorer-11

我们有两个带内容的div和第三个div,它是一个绝对位置的背景。

Container是一个弹性箱。

所有在Chrome和Safari中工作正常,但 Firefox和 IE11因素位于绝对定位div中,并在div之间分配空格,就像连续有3个div一样。

enter image description here

我已经制作了jsfiddle的例子。有没有办法解决这个错误? https://jsfiddle.net/s18do03e/2/



div.container {
  display: flex;
  flex-direction: row;
  width: 100%;
  height: 300px;
  justify-content: space-between;
  width: 100%;
  outline: 1px solid;
}
div.c1 {
  background: #aaeecc;
  width: 100px;
  position: relative;
  z-index: 50;
  top: 20px;
  display: flex;
}
div.c2 {
  background: #cceeaa;
  width: 200px;
  position: relative;
  z-index: 50;
  top: 20px;
  display: flex;
}
div.bg {
  background: #ccc;
  width: 100%;
  height: 100%;
  z-index: 0;
  left: 0px;
  top: 0px;
  position: absolute;
  display: flex;
}

<div class="container">
  <div class="c1">Content 1</div>
  <div class="c2">Content 2</div>
  <div class="bg">Background</div>
</div>
&#13;
&#13;
&#13;

4 个答案:

答案 0 :(得分:32)

更新:此问题已在Firefox中解决(截至2017年3月发布的v52)。问题仍存在于IE11中。

就像你在问题中写的那样:

  

Firefox计算绝对定位div,并在div之间分配空格,就像连续有3个div一样。

Firefox正在考虑第三个div(.bg),这是一个绝对定位的 in-flow flex项目,并将其计算到space-between计算中。 (IE11也是这样; Chrome和Edge会忽略它。)

显然,这不符合当前的flexbox规范:

  

4.1. Absolutely-Positioned Flex Children

     

因为它是一个流动的,一个绝对定位的flex的孩子   容器不参与flex布局。

以下是一些解决方法:

为什么不在其他两个之间移动绝对定位的div?

而不是:

<div class="container">
    <div class="c1">Content 1</div>
    <div class="c2">Content 2</div>
    <div class="bg">Background</div>
</div>

试试这个:

<div class="container">
    <div class="c1">Content 1</div>
    <div class="bg">Background</div>
    <div class="c2">Content 2</div>
</div>

&#13;
&#13;
div.container {
  display: flex;
  flex-direction: row;
  width: 100%;
  height: 300px;
  justify-content: space-between;
  width: 100%;
  outline: 1px solid;
}
div.c1 {
  background: #aaeecc;
  width: 100px;
  position: relative;
  z-index: 50;
  top: 20px;
  display: flex;
}
div.c2 {
  background: #cceeaa;
  width: 200px;
  position: relative;
  z-index: 50;
  top: 20px;
  display: flex;
}
div.bg {
  background: #ccc;
  width: 100%;
  height: 100%;
  z-index: 0;
  left: 0px;
  top: 0px;
  position: absolute;
  display: flex;
}
&#13;
<div class="container">
  <div class="c1">Content 1</div>
  <div class="bg">Background</div>
  <div class="c2">Content 2</div>
</div>
&#13;
&#13;
&#13;

或...从Flex容器中移除.bg

<div class="container">
    <div class="c1">Content 1</div>
    <div class="c2">Content 2</div>
</div>
<div class="bg">Background</div>

&#13;
&#13;
div.container {
  display: flex;
  flex-direction: row;
  width: 100%;
  height: 300px;
  justify-content: space-between;
  width: 100%;
  outline: 1px solid;
}
div.c1 {
  background: #aaeecc;
  width: 100px;
  position: relative;
  z-index: 50;
  top: 20px;
  display: flex;
}
div.c2 {
  background: #cceeaa;
  width: 200px;
  position: relative;
  z-index: 50;
  top: 20px;
  display: flex;
}
div.bg {
  background: #ccc;
  width: 100%;
  height: 100%;
  z-index: 0;
  left: 0px;
  top: 0px;
  position: absolute;
  display: flex;
}
&#13;
<div class="container">
  <div class="c1">Content 1</div>
  <div class="c2">Content 2</div>
</div>
<div class="bg">Background</div>
&#13;
&#13;
&#13;

或...使用flex order属性重新排列Flex项目。

将此添加到您的代码中:

.c2 { order: 1; }

&#13;
&#13;
div.container {
  display: flex;
  flex-direction: row;
  width: 100%;
  height: 300px;
  justify-content: space-between;
  width: 100%;
  outline: 1px solid;
}
div.c1 {
  background: #aaeecc;
  width: 100px;
  position: relative;
  z-index: 50;
  top: 20px;
  display: flex;
}
div.c2 {
  background: #cceeaa;
  width: 200px;
  position: relative;
  z-index: 50;
  top: 20px;
  display: flex;
  order: 1;
}
div.bg {
  background: #ccc;
  width: 100%;
  height: 100%;
  z-index: 0;
  left: 0px;
  top: 0px;
  position: absolute;
  display: flex;
}
&#13;
<div class="container">
  <div class="c1">Content 1</div>
  <div class="c2">Content 2</div>
  <div class="bg">Background</div>
</div>
&#13;
&#13;
&#13;

答案 1 :(得分:13)

正在发生这种情况,因为justify-content: space-between;均匀分配项目开头的第一项,结尾的最后一项。所以只需在<div class="bg">Background</div><div class="c1">Content 1</div>之间推杆<div class="c2">Content 2</div>  像这样

<div class="container">
    <div class="c1">Content 1</div>
    <div class="bg">Background</div>
    <div class="c2">Content 2</div>

</div>

您可以在https://developer.mozilla.org/en-US/docs/Web/CSS/justify-content

上查看原因

答案 2 :(得分:5)

有时无法重新订购内容,例如在使用::before::after时。在这些情况下,您可以手动order元素。

在您的情况下,您需要执行以下操作:

.c1 {
  order: -1;
}
.c2 {
  order: 10;
}

order属性是flex规范的一部分,可让您重新订购弹性项目(reference on MDN)。它包含了多种用途,非常方便。

我使用-1因为该值是序数,因此将其设置为负数可确保它在所有其他默认值之前,并且您不需要指定::before的值。出于同样的原因,即使向容器添加了一堆元素,使用10也可确保第二个div保持最后。您可以将其增加到100或其他任何内容。

但是,Firefox的行为似乎违反直觉。 position: absolute通常会移除通常dom流的元素,我希望该元素也可以从flex流中删除,就像在Safari和Chrome中一样。我不确定该规范是否澄清了这一点。

答案 3 :(得分:1)

作为替代方法,您可以在内容选择器中使用flex属性:

    div.c1 {
      background: #aaeecc;
      width: 100px;
      position: relative;
      z-index: 50; top: 20px;
      display: flex;

      flex: 1; /* add this */
    }

这将设置flex-grow。它可能不完全是你需要的,但也许它可以帮助其他人无法重新排序内容div或从flex包装器中取出它们。

以下是演示: https://jsfiddle.net/s18do03e/14/