Élément flex absolument positionné n'est pas retiré du flux normal dans IE11

Nous avons deux divs avec le contenu et un troisième div qui est un arrière-plan avec la position absolue.

Le conteneur est une flexbox.

Tout fonctionne bien dans Chrome et Safari, mais Firefox et IE11 facteurs dans le div positionné absolu, et distribue l'espace entre divs comme il y a 3 divs dans une rangée.

entrez la description de l'image ici

J'ai fait un exemple jsfiddle. Est-il possible de résoudre ce problème bug? 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>
26
demandé sur Michael_B 2015-10-07 14:30:20

4 réponses

Cela se produit parce que justify-content: space-between; distribuez uniformément les éléments le premier élément au début, le dernier à la fin. Donc, juste putt <div class="bg">Background</div> entre <div class="c1">Content 1</div> et <div class="c2">Content 2</div> comme ça

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

</div>

, Vous pouvez voir la raison sur https://developer.mozilla.org/en-US/docs/Web/CSS/justify-content

12
répondu Guru 2015-10-07 11:59:41

Mise à jour: ce problème a été résolu dans Firefox (à partir de v52, publié en mars 2017). Le problème existe toujours dans IE11.


Comme vous l'avez écrit dans la question:

Firefox calcule div positionné absolu, et distribue l'espace entre divs comme il y a 3 divs dans une rangée.

Firefox considère le troisième div (.bg), qui est absolument positionné, un élémentin-flow flex et l'affacturage dans son calcul space-between. (IE11 le fait aussi; Chrome et Edge l'ignorent.)

De toute évidence, cela n'est pas conforme à la spécification flexbox actuelle:

4.1. Enfants Flex Absolument Positionnés

Comme il est hors-flux, un enfant absolument positionné d'un flex conteneur ne participe pas à la mise en page flex.

Voici quelques solutions de contournement:

pourquoi ne pas déplacer le div absolument positionné entre l'autre deux?

Au lieu de ceci:

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

, Essayez ceci:

<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>

OU... supprimer .bg sur le conteneur flex:

<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>

OU... utilisez la propriété flex order pour réorganiser les éléments flex.

Ajoutez ceci à votre code:

.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>
29
répondu Michael_B 2018-01-09 13:42:38

Parfois, il N'est pas possible de réorganiser des choses, par exemple lorsque vous utilisez ::before et ::after. Dans ces cas, vous pouvez manuellement order les éléments.

Dans votre cas, vous devez faire:

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

La propriété order fait partie de la spécification flex et vous permet de réorganiser les éléments flex (référence sur MDN). Il est très pratique à des fins multiples, cela inclus.

J'ai utilisé -1 parce que la valeur est ordinale, donc le définir sur un nombre négatif garantit qu'il précède tout autres valeurs par défaut et vous n'avez pas besoin de spécifier la valeur pour ::before. Pour la même raison, l'utilisation de 10 garantit que la deuxième div arrive en dernier même si vous ajoutez un tas d'éléments au conteneur. Vous pouvez augmenter cela à 100 ou autre.

Pourtant, le comportement de Firefox semble contre-intuitif. position: absolute supprime normalement l'élément pour le flux Dom habituel et je m'attendrais à ce que cet élément soit également supprimé du flux flex, tout comme dans Safari et Chrome. Je ne suis pas sûr de savoir si le spec clarifiez ceci.

5
répondu Emanuele Feliziani 2016-03-01 20:24:55

Comme alternative, vous pouvez utiliser la propriété flex dans le (s) sélecteur (s) de contenu:

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

      flex: 1; /* add this */
    }

Cela définira le flex-grow. Ce n'est peut-être pas exactement ce dont vous avez besoin, mais peut-être que cela aide quelqu'un d'autre qui ne peut pas réorganiser les divs de contenu ou les sortir du wrapper flex.

Voici la démo: https://jsfiddle.net/s18do03e/14/

0
répondu Constantin Stan 2016-02-29 11:54:24