Абсолютно позиционированный элемент гибкости не удаляется из нормального потока в IE11
У нас есть два div с содержимым и третий div, который является фоном с абсолютным положением.
Контейнер - это flexbox.
Все работает отлично в Chrome и Safari, но Firefox и IE11 факторов в абсолютном позиционированном div и распределяет пространство между div, например, 3 divs в строке.
![введите описание изображения здесь]()
Я сделал пример 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>
Ответы
Ответ 1
Это происходит потому, что justify-content: space-between;
равномерно распределяет элементы. Первый элемент в начале, последний в конце. Так что просто putt <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
ОБНОВЛЕНИЕ:. Эта проблема была решена в Firefox (начиная с версии v52, выпущенной в марте 2017 г.). Проблема все еще существует в IE11.
Как вы писали в вопрос:
Firefox вычисляет абсолютный позиционированный div и распределяет пространство между div, например, 3 divs в строке.
Firefox рассматривает третий div (.bg
), который абсолютно позиционируется, является гибким элементом потока и факторизует его в свой расчет space-between
. (IE11 тоже делает это, Chrome и Edge игнорируют его.)
Очевидно, что это не соответствует текущей спецификации flexbox:
4.1. Абсолютно-размещенные дети 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>
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>
Ответ 3
Иногда невозможно переупорядочить материал, например, при использовании ::before
и ::after
. В этих случаях вы можете вручную order
использовать элементы.
В вашем случае вам нужно будет:
.c1 {
order: -1;
}
.c2 {
order: 10;
}
Свойство order
является частью спецификации flex
и позволяет вам переупорядочивать элементы гибкости (ссылка на 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 */
}
Это установит гибкость. Возможно, это не совсем то, что вам нужно, но, возможно, это помогает кому-то другому, который не может изменить порядок содержимого div или вытащить их из оболочки flex.
Вот демо:
https://jsfiddle.net/s18do03e/14/