绝对定位的弹性项目不会从 IE11 中的正常流程中删除
Posted
技术标签:
【中文标题】绝对定位的弹性项目不会从 IE11 中的正常流程中删除【英文标题】:Absolutely positioned flex item is not removed from the normal flow in IE11 【发布时间】:2016-01-04 14:46:08 【问题描述】:我们有两个带有内容的 div 和第三个带有绝对位置的背景的 div。
容器是一个弹性盒子。
在 Chrome 和 Safari 中一切正常,但 Firefox 和 IE11 会考虑绝对定位的 div,并在 div 之间分配空间,就像连续 3 个 div 一样。
我制作了 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>
【问题讨论】:
截至 12 月的 flex-container 内的绝对定位。 2019:codepen.io/ekadagami/pen/mdyPybq 【参考方案1】:更新:此问题已在 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 的绝对定位子代 容器不参与弹性布局。
以下是一些解决方法:
为什么不在另外两个之间移动绝对定位的 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>
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="bg">Background</div>
<div class="c2">Content 2</div>
</div>
或者...从 flex 容器中删除 .bg
:
<div class="container">
<div class="c1">Content 1</div>
<div class="c2">Content 2</div>
</div>
<div class="bg">Background</div>
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>
<div class="bg">Background</div>
或者...使用 flex order
属性重新排列 flex 项。
将此添加到您的代码中:
.c2 order: 1;
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;
<div class="container">
<div class="c1">Content 1</div>
<div class="c2">Content 2</div>
<div class="bg">Background</div>
</div>
【讨论】:
这是一个非常彻底的答案。看准队友。 请注意,Firefox(和 IE)有这种行为,因为它是 required by an older revision of the flexbox spec —— abspos flex children 上的规范文本随着时间的推移发生了很大变化。不过好消息——Firefox 52 中的当前规范行为 will ship! (计划于 2017 年 3 月 7 日发布) 干得好,最好的答案在这里。我建议在其他建议之前使用“order”属性,因为这确实是一个 CSS 问题,并且最后对背景 div 进行排序更好,并且可能无法将其从容器中删除。order
到底在做什么?
它将源中的第二个.c2
元素移动到第三个位置(more info)。 @DrazenBjelovuk【参考方案2】:
之所以发生,是因为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看到原因
【讨论】:
【参考方案3】:有时无法重新订购商品,例如使用::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 中一样。我不确定规范是否澄清了这一点。
【讨论】:
【参考方案4】:作为替代方案,您可以在内容选择器中使用 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/
【讨论】:
以上是关于绝对定位的弹性项目不会从 IE11 中的正常流程中删除的主要内容,如果未能解决你的问题,请参考以下文章