Абсолютно позиционированный элемент Flex не удаляется из нормального потока в IE11
У нас есть два 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>
4 ответа
Это происходит потому что 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
ОБНОВЛЕНИЕ: Эта проблема была решена в Firefox (начиная с версии v52, выпущенной в марте 2017 года). Проблема все еще существует в IE11.
Как вы написали в вопросе:
Firefox вычисляет абсолютный позиционированный div и распределяет пространство между div, как в строке 3 div.
Firefox рассматривает третий div (.bg
), который является абсолютно позиционированным, гибким элементом в потоке и делит его на свои space-between
расчет. (IE11 делает это тоже; Chrome и Edge игнорируют это.)
Понятно, что это не соответствует текущей спецификации flexbox:
4.1. Абсолютно позиционированные гибкие дети
Поскольку это вне потока, абсолютно позиционированный дочерний элемент гибкого контейнера не участвует в гибком макете.
Вот некоторые обходные пути:
Почему бы не переместить абсолютно позиционированный 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>
ИЛИ... удалить .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>
ИЛИ... используйте гибкий order
свойство переупорядочивать гибкие элементы.
Добавьте это к своему коду:
.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>
Иногда невозможно изменить порядок вещей, например, при использовании ::before
а также ::after
, В этих случаях вы можете вручную order
элементы.
В вашем случае вам нужно будет сделать:
.c1 {
order: -1;
}
.c2 {
order: 10;
}
order
собственность является частью flex
spec и позволяет вам переупорядочивать flex-элементы ( ссылка на MDN). Это очень удобно для нескольких целей, в том числе.
я использовал -1
поскольку значение является порядковым, поэтому установка его в отрицательное число гарантирует, что оно предшествует всем другим значениям по умолчанию, и вам не нужно указывать значение для ::before
, По той же причине, используя 10
гарантирует, что второй div будет последним, даже если вы добавите кучу элементов в контейнер. Вы можете увеличить это до 100
или что угодно.
Тем не менее, поведение Firefox кажется нелогичным. position: absolute
обычно удаляет элемент для обычного потока DOM, и я ожидаю, что этот элемент будет удален из flex
текут так же, как в Safari и Chrome. Я не уверен, что спецификация проясняет это.
В качестве альтернативы вы можете использовать свойство flex внутри селектора контента:
div.c1 {
background: #aaeecc;
width: 100px;
position: relative;
z-index: 50; top: 20px;
display: flex;
flex: 1; /* add this */
}
Это установит flex-grow. Это может быть не совсем то, что вам нужно, но, возможно, это поможет кому-то еще, кто не может переупорядочить элементы содержимого или извлечь их из flex-оболочки.
Вот демоверсия: https://jsfiddle.net/s18do03e/14/