web-dev-qa-db-fra.com

Comment rendre flexbox enfants 100% de la taille de leur parent?

J'essaie de remplir l'espace vertical d'un élément flex à l'intérieur d'une flexbox.

.container {
  height: 200px;
  width: 500px;
  display: flex;
  flex-direction: row;
}
.flex-1 {
  width: 100px;
  background-color: blue;
}
.flex-2 {
  position: relative;
  flex: 1;
  background-color: red;
}
.flex-2-child {
  height: 100%;
  width: 100%;
  background-color: green;
}
<div class="container">
  <div class="flex-1"></div>
  <div class="flex-2">
    <div class="flex-2-child"></div>
  </div>
</div>

Et voici le JSFiddle

flex-2-child ne remplit pas la hauteur requise, sauf dans les deux cas où:

  1. flex-2 a une hauteur de 100% (ce qui est étrange, car un élément flex a 100% par défaut + il est bogué dans Chrome)
  2. flex-2-child a une position absolue ce qui est également gênant

Cela ne fonctionne pas dans Chrome ou Firefox actuellement.

367
Raz

J'ai répondu à une question similaire ici .

Je sais que vous avez déjà dit que position: absolute; est gênant mais que cela fonctionne. Voir ci-dessous pour plus d'informations sur la résolution du problème de redimensionnement.

Voir aussi ceci jsFiddle pour une démo, même si je n’ai ajouté que les préfixes webkit, donc ouvert dans Chrome.

Vous avez essentiellement 2 questions que je traiterai séparément.

  1. Obtenir que l'enfant d'un élément flex remplisse 100% de hauteur
    • Définissez position: relative; sur le parent de l'enfant.
    • Définissez position: absolute; sur l'enfant.
    • Vous pouvez ensuite définir largeur/hauteur selon vos besoins (100% dans mon échantillon).
  2. Correction du "décalage" de défilement du redimensionnement dans Chrome
    • Mettez overflow-y: auto; sur le div à défilement.
    • Le div à défilement doit avoir une hauteur explicite spécifiée. Mon échantillon a déjà une hauteur de 100% mais si aucun n'est déjà appliqué, vous pouvez spécifier height: 0;

Voir ceci réponse pour plus d'informations sur le problème de défilement.

264
Brett Postin

Si je comprends bien, vous voulez que flex-2-child remplisse la hauteur et la largeur de son parent, de sorte que la zone rouge soit entièrement recouverte par le vert?

Si tel est le cas, il vous suffit de configurer flex-2 pour utiliser flexbox:

.flex-2 {
    display: flex;  
}

Puis dites à flex-2-child de devenir flexible:

.flex-2-child {    
    flex: 1;
}

Voir http://jsfiddle.net/2ZDuE/10/

La raison en est que flex-2-child n'est pas un élément flexbox, mais son parent l'est.

206
David Storey

Utilisez align-items: 'stretch'

Semblable à la réponse de David Storey, mon travail est

.flex-2 {
    display: flex;  
    align-items: 'stretch';
}

Alternativement à align-items, vous pouvez utiliser align-self uniquement sur l’élément .flex-2-child que vous voulez étirer.

111
B T

Je suppose que le comportement de Chrome est plus conforme à la spécification CSS (bien que ce soit moins intuitif). Selon Flexbox spec, la valeur par défaut stretch de align-self propriété modifie uniquement le utilisé valeur de la "propriété de taille transversale" de l'élément (height, dans ce cas). Et, si je comprends bien la spécification CSS2.1 , les hauteurs en pourcentage sont calculées à partir de la valeur spécifiée du height du parent, pas sa valeur utilisée. La valeur spécifiée de height du parent n'est affectée par aucune propriété flex et reste auto.

La définition explicite de height: 100% permet formellement de calculer le pourcentage de hauteur de l'enfant, comme si vous définissiez height: 100% à html permet de calculer le pourcentage de hauteur de body en CSS2.1.

21
Ilya Streltsyn

J'ai trouvé la solution par moi-même, supposons que vous ayez le CSS ci-dessous:

.parent {
  align-items: center;
  display: flex;
  justify-content: center;
}

.child {
  height: 100%; <- didn't work
}

Dans ce cas, régler la hauteur à 100% ne fonctionnera pas. Ce que je fais est donc de définir la règle margin-bottom sur auto, comme ceci:

.child {
  margin-bottom: auto;
}

et l’enfant sera aligné sur le sommet du parent, vous pouvez quand même utiliser la règle align-self si vous préférez.

.child {
  align-self: flex-start;
}
9
user3896501

Une idée serait que display:flex; avec flex-direction: row; remplit la container div avec .flex-1 et .flex-2, mais cela ne signifie pas que .flex-2 a une valeur par défaut height:100%; même si elle est étendue à toute la hauteur et pour avoir un élément enfant (.flex-2-child) avec height:100%;, vous devrez définir le parent sur height:100%; ou utiliser display:flex; avec flex-direction: row; sur le .flex-2 aussi.

D'après ce que je sais, display:flex ne prolongera pas la hauteur de tous vos éléments enfants à 100%.

Une petite démo, enlevé la hauteur de .flex-2-child et utilisé display:flex; sur .flex-2: http://jsfiddle.net/2ZDuE/3/

4
rmagnum2002

html

<div class="container">
    <div class="flex-1"></div>
    <div class="flex-2">
        <div class="flex-2-child"></div>
    </div>
</div>

css

.container {
    height: 200px;
    width: 500px;
    display: -moz-box;
    display: -webkit-flexbox;
    display: -ms-flexbox;
    display: -webkit-flex;
    display: -moz-flex;
    display: flex;
    -webkit-flex-direction: row;
    -moz-flex-direction: row;
    -ms-flex-direction: row;
    flex-direction: row;
}
.flex-1 {
   flex:1 0 100px;
    background-color: blue;
}
.flex-2 {
    -moz-box-flex: 1;
    -webkit-flex: 1;
    -moz-flex: 1;
    -ms-flex: 1;
    flex: 1 0 100%;
    background-color: red;
}
.flex-2-child {
    flex: 1 0 100%;
    height:100%;
    background-color: green;
}

http://jsfiddle.net/2ZDuE/750/

3
Carol McKay