Flex base 100% nella colonna flexbox: pieno altezza in Firefox, non in Cromo

Vorrei una colonna di div, in ogni numero, ogni con larghezza 100% altezza e 100% di un genitore div, così è visibile inizialmente, e gli altri overflow del genitore verso il basso. Ho impostato il div per avere flex: 0 0 100%;, all’interno di un genitore div con display: flex e flex-direction: column per raggiungere questo obiettivo.

Padre div è di per sé di unknown altezza, quindi è anche un bambino di un display: flex e flex-direction: column, set per flex: 1 0 0 a prendere spazio rimanente nel suo contenitore.

In Firefox l’uscita è come la vorrei:

Flex base 100% nella colonna flexbox: pieno altezza in Firefox, non in Cromo

Tuttavia, non Chrome:

Flex base 100% nella colonna flexbox: pieno altezza in Firefox, non in Cromo

Come posso ottenere il stile Firefox a Chrome, senza Javascript?

Si può vedere in azione a http://plnkr.co/edit/WnAcmwAPnFaAhqqtwhLL?p=preview, così come la corrispondente versione con flex-direction: row, che funziona in modo coerente sia su Firefox e Chrome.

Di riferimento per l’intero CSS

.wrapper {
  display: flex;
  flex-direction: column;
  height: 150px;
  width: 200px;
  border: 4px solid green;
  margin-bottom: 20px;
}

.column-parent {
  flex: 1 0 0;
  display: flex;
  flex-direction: column;
  border: 2px solid blue;
}

.column-child {
  flex: 0 0 100%;
  border: 2px solid red;
}

e HTML

<div class="wrapper">
  <p>Some content of unknown size</p>
  <div class="column-parent">
    <div class="column-child">
      Should be inside green
    </div>
    <div class="column-child">
      Should be outside green
    </div>
  </div>
</div>



4 Replies
  1. 15

    Come indicato in Abhitalks risposta, c’è un bug (o una diversa interpretazione della norma), in modo Chrome gestisce il altezza attributo qui.

    Ho trovato un hack che funzioni sia in Chrome, FF e IE

    L’unico problema è che si ned per avere più regole posible i bambini ci sono.

    Il trucco è quello di impostare il flex-direzione per riga, impostare il flex-base (che è ora la larghezza al 100%, e quindi a tradurre gli elementi

    CSS:

    .container {
        border: solid 2px blue;
        height: 200px;
        width: 200px;
        display: flex;
        flex-direction: column;
        position: relative;
    }
    
    .filler {
        border: solid 1px black;
        flex: 0 0 80px;
        background-color: lightgreen;
        transition: flex 1s;
    }
    
    .container:hover .filler {
        flex: 0 0 40px;
    }
    
    .test {
        border: solid 1px red;
        flex: 1 0 25px;
        display: flex;
        flex-direction: row;
        position: relative;
    }
    
    .child {
        background-color: rgba(200, 0, 0, 0.26);
        flex: 0 0 100%; 
    }
    
    .child:nth-child(2) {
        background-color: rgba(255, 255, 0, 0.48);
        transform: translateX(-100%) translateY(100%);
    }
    
    .child:nth-child(3) {
        background-color: rgba(173, 216, 230, 0.28);
        transform: translateX(-200%) translateY(200%);
    }

    HTML:

    <div class="container">
        <div class="filler"></div>
        <div class="filler"></div>
        <div class="test">
        	   <div class="child">1</div>
        	   <div class="child">2</div>
        	   <div class="child">3</div>
        </div>
    </div>

    Se ci potrebbe essere un altro bambino, si avrebbe bisogno di un nth-child(4) regola, e così via

    Ho aggiunto un effetto hover per verificare come la dimensione adatta

    • In realtà ho appoggiato la soluzione che hai postato inizialmente… puoi postare una risposta? Penso che sembrano sufficientemente diversi per garantire che.
    • Ciao ! Volevo spaccare la risposta, e vedo che hai accettato… Ora non so cosa fare. Sentitevi liberi di modificarlo se vuoi 🙂
    • Penso che sarebbe ancora meglio dividere, solo perchè sono diverse soluzioni. Ho il sospetto che io ti premio per la bontà di quello che hai postato prima.
  2. 19

    Questo sembra essere un bug di Chrome. Simili a quelli riportati qui (problema 428049) e forse in relazione (problema 346275).

    Questo dice:

    - Browser dovrebbero risolvere percentuali sul flex voce del bambino, *se* il suo flex-base è definitivo. 
    - Gecko è *sempre* risoluzione di percentuali indipendentemente dal flex-base. 
    - Chrome non è *mai* risoluzione di percentuali, a prescindere dal flex-base. 

    Sommariamente, Chrome non è la risoluzione per cento altezze sul flex-voce del bambino (anche se il bambino è un flex-voce), mentre tutti gli altri browser.

    Questo può essere dimostrato nella seguente frammento: (Il violino qui)

    CSS:

    * { box-sizing: border-box; margin: 0; padding: 0; }
    div.wrap {
        height: 120px; width: 240px; margin: 0px 12px;
        border: 1px solid blue; float: left;
        display: flex; flex-direction: column;    
    }
    div.parent {
        flex: 0 0 100%;
        border: 1px solid green; 
        display: flex; flex-direction: column;    
    }
    div.item {
        flex: 0 0 100%;
        border: 1px solid red;
    }

    HTML:

    <div class="wrap">
        <div class="item">a</div>
        <div class="item">b</div>
        <div class="item">c</div>
    </div>
    <div class="wrap">
        <div class="parent">
            <div class="item">a</div>
            <div class="item">b</div>
            <div class="item">c</div>
        </div>
    </div>

    Il secondo div dovrebbe mostrare lo stesso comportamento come il primo. Altri browser (IE11, Edge, FF39) vedi correttamente. Chrome non riesce qui e non risolvere div.item correttamente. Ha bisogno di un altezza fissa su suo padre, senza il quale non utilizza min-content come la sua altezza e quindi non in overflow.

    Considerando che, nel primo div, il div.items sono risolti correttamente e overflow di conseguenza. Questo è perché c’è un altezza fissa sul padre (cioè div.wrap)


    Possibile Soluzione:

    Come soluzione alternativa, se si è sicuri di avere solo due elementi (p e div) all’interno del wrapper, allora si potrebbe dare un 50% altezza. È necessario fornire un height:50% al tuo .column-parent. Chrome ha bisogno di un altezza fissa genitore, come illustrato sopra.

    Poi tutto funzionerà come avete bisogno di.

    Demo Violino: http://jsfiddle.net/abhitalks/kqncm65n/

    Rilevanti CSS:

    .wrapper > p { flex: 0 0 50%; }  /* this can be on flex-basis */
    .column-parent {
        flex: 1 0 auto; height: 50%; /* but, this needs to be fixed height */
        display: flex; flex-direction: column;
        border: 2px solid blue;
    }
    .column-child {
        flex: 0 0 100%;              /* this flex-basis is then enough */
        border: 2px solid red;
    }

    PS: non Vi sembra anche essere differenze nel modo in cui jsfiddle e plnkr di rendering. Non so perché, ma a volte ottengo risultati diversi!

    • HTML è correttamente digitato questo violino. Che cosa può essere il motivo per cui non stampa i valori?
  3. 10

    La mia risposta precedente è un hack che sfrutta una particolare configurazione del layout desiderato.

    Un modo alternativo, più in generale, di ottenere intorno a questo bug di Chrome è quello di utilizzare un elemento intermedio il layout, e impostare la dimensione dell’elemento per mezzo di top: 0px e il bottom: 0px. (anziché altezza: 100%) C’è ancora un bug nel modo in Chrome gestisce il calcolo, che necessita di un falso animazione per rendere regolare correttamente

    CSS:

    .container {
        border: solid 2px blue;
        height: 200px;
        width: 200px;
        display: flex;
        flex-direction: column;
        position: relative;
    }
    
    .filler {
        border: solid 1px black;
        flex: 0 0 94px;
        background-color: lightgreen;
        transition: 1s;
    }
    
    .container:hover .filler {
        flex: 0 0 50px;
    }
    
    .test {
        border: solid 1px red;
        flex: 1 0 25px;
        display: flex;
        flex-direction: row;
        position: relative;
    }
    
    @-webkit-keyframes adjust2 {
        0% {flex-basis: 100%;}
      100% {flex-basis: 100.1%;}
    }
    .child {
        background-color: rgba(200, 0, 0, 0.26);
        width:  100%;
        height: 100%;
        flex: 1 0 100%;
        -webkit-animation: adjust2 1s infinite; /* only needed for webkit bug */
    }
    
    .intermediate {
        width:  100%;
        position: absolute;
        top: 0px;
        bottom: 0px;
        display: flex; 
        flex-direction: column; 
    }
    
    .child:nth-child(n+2) {
        background-color: rgba(255, 255, 0, 0.48);
    }
    
    .child:nth-child(n+3) {
        background-color: rgba(173, 216, 230, 0.28);
    }

    HTML:

    <div class="container">
        <div class="filler"></div>
        <div class="test">
            <div class="intermediate">
        	       <div class="child"></div>
        	       <div class="child"></div>
        	       <div class="child"></div>
            </div>
        </div>
    </div>

  4. 8

    Quali con l’aggiunta di 100% per il contenitore:

    .column-parent {
      flex: 1 0 100%;
    }

    E flex-crescere fino a 1 nel contenuto dell’elemento senza regolazione flex base:

    .column-child {
      flex: 1 0 0;
    }

    Ecco come sarebbe il risultato: http://plnkr.co/edit/H25NQxLtbi65oaltNVax?p=preview

    • Ah non del tutto… Ci sono anche un numero imprecisato di elementi figlio. Se ci sono 3, questa tecnica non fa quello che vorrei: plnkr.co/modifica/21KD5kuIw3yLKX2NL70l?p=anteprima .
    • Hai assolutamente ragione. Se non siamo in grado di conoscere il numero di elementi del bambino in anticipo, questo tipo di alternative non avrebbe funzionato.

Lascia un commento