Абсолютно позиционированный элемент гибкости не удаляется из нормального потока в 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/