Come posso rendere Flexbox i bambini al 100% di altezza dei loro genitori?


459

Sto cercando di riempire lo spazio verticale di un oggetto flessibile all'interno di un 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>

Ed ecco il JSFiddle

flex-2-child non riempie l'altezza richiesta tranne nei due casi in cui:

  1. flex-2 ha un'altezza del 100% (il che è strano perché un articolo flessibile ha un 100% di default + è buggy in Chrome)
  2. flex-2-child ha una posizione assoluta che è anche scomoda

Questo non funziona attualmente in Chrome o Firefox.


qual è il problema con l'utilizzo dell'altezza: 100%; per .flex-2?
rmagnum2002,

Sfida lo scopo dell'elemento flessibile che è quello di riempire il contenuto da solo e mi sta dando il bug più strano in cromo in cui l'altezza torna a zero ogni volta che ridimensiono la finestra
Raz

3
In realtà, l'ultima versione di Firefox è l'unica che funziona correttamente
Raz

1
Attualmente, ci sono differenze significative nel comportamento tra i browser quando si tratta di altezze percentuali il rendering in FlexBox: stackoverflow.com/a/35537510/3597276
Michael Benjamin

2
Sì, Chrome ha alcuni problemi, specialmente con i flexbox nidificati. Ad esempio ho una scatola flessibile nidificata con i bambini che hanno, height:100%ma stanno invece eseguendo il rendering con altezza naturale. E la cosa strana è che se cambio la loro altezza in auto, allora si renderizzano height:100%come stavo cercando di fare. Non è assolutamente intuitivo se è così che dovrebbe funzionare.
trusktr,

Risposte:


238

Uso align-items: stretch

Simile alla risposta di David Storey, la mia soluzione è:

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

In alternativa align-items, puoi usare align-selfsolo l' .flex-2-childoggetto che vuoi allungare.


7
stretch: questa dovrebbe essere la risposta scelta.
Dave Everitt,

1
Sicuramente questa è di gran lunga la migliore risposta alla domanda. Funziona perfettamente.
marcias,

Sì, questa è davvero la migliore risposta a questa domanda.
Øyvind Bråthen,

20
non dimenticare di rimuovere anche height: 100%dal componente figlio che desideri la stessa altezza del genitore
Ilham Wahabi GX

Per favore aggiungi la rimozione height: 100%alla risposta - ho quasi rinunciato e l'ho visto solo all'ultimo momento prima di tornare a absolute- che si presenta con tutti i tipi di problemi.
Peter,

274

Ho risposto a una domanda simile qui .

So che hai già detto che position: absolute;è scomodo ma funziona. Vedi sotto per ulteriori informazioni sulla risoluzione del problema di ridimensionamento.

Vedi anche questo jsFiddle per una demo, anche se ho aggiunto solo i prefissi webkit così aperti in Chrome.

Fondamentalmente hai 2 problemi che tratterò separatamente.

  1. Far riempire il bambino di un oggetto flessibile al 100% di altezza
    • Impostato position: relative;sul genitore del bambino.
    • Impostare position: absolute;sul bambino.
    • È quindi possibile impostare larghezza / altezza come richiesto (100% nel mio campione).
  2. Risolto il problema del ridimensionamento "stranezza" in Chrome
    • Indossa overflow-y: auto;il div scorrevole.
    • Il div scorrevole deve avere un'altezza esplicita specificata. Il mio campione ha già un'altezza del 100% ma se non ne è già stato applicato nessuno, è possibile specificareheight: 0;

Vedi questa risposta per ulteriori informazioni sul problema di scorrimento.


10
Punto 1) funziona perfettamente in Chrome, Firefox non ha bisogno della posizione assoluta.
yuri,

224

Se ho capito bene, vuoi che flex-2-child riempia l'altezza e la larghezza del suo genitore, in modo che l'area rossa sia completamente coperta dal verde?

In tal caso, devi solo impostare flex-2 per usare flexbox:

.flex-2 {
    display: flex;  
}

Quindi dì a flex-2-child di diventare flessibile:

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

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

Il motivo è che flex-2-child non è un oggetto flexbox, ma lo è il suo genitore.


Come posso fare lo stesso, solo con un'altezza del 100% e ogni bambino ha il 50/50?
Ricky Levi,

7
Tieni presente che se usi "align-items: center" non sarai in grado di usare questa correzione poiché i tuoi oggetti ora diventeranno di uguale altezza.
Neil Monroe,

10
@NeilMonroe Puoi ancora usare align-items: centerse usi align-self: stretchsolo un bambino.
BT,

1
Ciao @David, ho provato la tua soluzione, funziona bene per la direzione flessibile: layout di riga, sembra non funzionare con la direzione flessibile: layout di colonna, o ho qualche posto sbagliato nel codice. Potresti aiutare a verificare perché in questo violino jsfiddle.net/78o54Lmv , la scatola interna non occuperà l'intera altezza del suo genitore?
huan feng,

Devo aggiungere min-height: 100vh;a .flex-2elemento per rendere funziona. Grazie per l'aiuto!
Tenaciousd93,

24

Suppongo che il comportamento di Chrome sia più coerente con le specifiche CSS (anche se è meno intuitivo). Secondo le specifiche Flexbox, il stretchvalore predefinito della align-selfproprietà cambia solo il valore utilizzato della "proprietà di dimensione incrociata" dell'elemento ( height, in questo caso). E, come ho capito le specifiche CSS2.1 , le altezze percentuali sono calcolate dal valore specificato del genitore height, non dal suo valore usato. Il valore specificato del genitore heightnon è influenzato da alcuna proprietà flessibile ed è ancora auto.

L'impostazione esplicita height: 100%rende formalmente possibile calcolare l'altezza percentuale del figlio, proprio come l'impostazione height: 100%per htmlconsentire di calcolare l'altezza percentuale di bodyin CSS2.1.


2
Esattamente! Per metterlo in pratica, basta aggiungere height:100%a .flex-2. Ecco il jsfiddle .
CourtDemone,

7
Il comportamento di Chrome è più coerente con l'interpretazione del team Chrome delle specifiche CSS. Sebbene possa essere interpretato in questo modo, ci sono modi molto migliori di interpretarlo, nessuno dei quali non ci avrebbe intrappolati in questo bazar, comportamenti fastidiosi e fastidiosi. Avrebbero dovuto pensarci di più.
WraithKenny,

1
@RickDoesburg, questo è stato più di un anno fa, ma credo che dovessi ricorrere ad elementi ad altezza fissa. Vorrei che questi browser si comportassero insieme. Sto davvero iniziando a non gradire lo spazio mobile.
Giordania

1
L'impostazione di un figlio di un contenitore flexbox verticale height: 100%per me sta dando risultati molto strani per me in Chrome. Sembra che ciò determini che l '"altezza specificata" sia impostata sull'altezza totale del contenitore , piuttosto che sull'altezza dell'elemento stesso, quindi provoca lo scorrimento indesiderato quando altri elementi hanno dimensioni calcolate rispetto ad esso.
Jules il

13

Ho trovato la soluzione da solo, supponiamo che tu abbia il CSS qui sotto:

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

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

In questo caso, l'impostazione dell'altezza al 100% non funzionerà, quindi quello che faccio è impostare la margin-bottomregola su auto, come:

.child {
  margin-bottom: auto;
}

e il bambino sarà allineato alla parte superiore del genitore, puoi anche usare la align-selfregola se preferisci.

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

Un bel trucco, ma il problema è: se child è una barra laterale e ha un colore di sfondo, lo spazio del margine è ancora bianco.
Boris Burkov,

La cosa fantastica di questa soluzione è che l'altezza del genitore può essere dinamica! Le soluzioni precedenti richiedono che il genitore abbia un'altezza impostata. Grazie per questo.
Bribbons

4

Un'idea sarebbe che display:flex;con flex-direction: row;sta riempiendo il containerdiv con .flex-1e .flex-2, ma ciò non significa che .flex-2abbia un valore predefinito height:100%;anche se è esteso a tutta altezza e per avere un elemento figlio ( .flex-2-child) con height:100%;dovrai impostare il genitore height:100%;o usare display:flex;anche con flex-direction: row;il .flex-2div.

Da quello che so display:flexnon estenderemo l'altezza di tutti gli elementi di tuo figlio al 100%.

Una piccola demo, rimossa l'altezza da .flex-2-childe utilizzata display:flex;su .flex-2: http://jsfiddle.net/2ZDuE/3/


3

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/


0

Questo può essere risolto anche con align-self: stretch;l'elemento che vogliamo allungare.

A volte è desiderabile allungare solo un elemento in una configurazione di flexbox.

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


-7

.container {. . . . align-items: tratto; . . . . }


5
Benvenuto in StackOverflow. Devi spiegare completamente la tua risposta e ciò che contribuisce che è diverso dalle risposte esistenti. Vedere stackoverflow.com/help/how-to-answer
Simon.SA

1
La tua risposta sembra essere la stessa di BT (scritta con tre anni di anticipo) ma espressa molto più male.
Quentin,

-12

Questa è la mia soluzione usando css +

Prima di tutto se il primo figlio (flex-1) dovrebbe essere 100px non dovrebbe essere flessibile. In css + infatti puoi impostare elementi flessibili e / o statici (colonne o righe) e il tuo esempio diventa facile come questo:

<div class="container">
  <div class="EXTENDER">
    <div class="COLS">
      <div class="CELL _100px" style="background-color:blue">100px</div>
      <div class="CELL _FLEX" style="background-color:red">flex</div>
    </div>
  </div>
</div>

contenitore css:

.container {
    height: 200px;
    width: 500px;
    position:relative;
}

e ovviamente includono css + 0,2 core

senti il violino

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.