Soluzione
Utilizzare contenitori flessibili nidificati.
Sbarazzarsi delle altezze percentuali. Sbarazzarsi delle proprietà della tabella. Sbarazzarsi di vertical-align. Evitare il posizionamento assoluto.Attacca con flexbox fino in fondo.
Applicare display: flexsull'elemento flessibile ( .item), rendendolo un contenitore flessibile. Questo imposta automaticamente align-items: stretch, che dice al bambino ( .item-inner) di espandere l'intera altezza del genitore.
Importante: rimuovere le altezze specificate dagli oggetti flessibili per far funzionare questo metodo. Se un bambino ha un'altezza specificata (ad es. height: 100%), Ignorerà la align-items: stretchprovenienza dal genitore. Perché l' stretchimpostazione predefinita funzioni, è necessario calcolare l'altezza del bambino auto (spiegazione completa ).
Prova questo (nessuna modifica a HTML):
.container {
display: flex;
flex-direction: column;
height: 20em;
border: 5px solid black
}
.item {
display: flex; /* new; nested flex container */
flex: 1;
border-bottom: 1px solid white;
}
.item-inner {
display: flex; /* new; nested flex container */
flex: 1; /* new */
/* height: 100%; <-- remove; unnecessary */
/* width: 100%; <-- remove; unnecessary */
/* display: table; <-- remove; unnecessary */
}
a {
display: flex; /* new; nested flex container */
flex: 1; /* new */
align-items: center; /* new; vertically center text */
background: orange;
/* display: table-cell; <-- remove; unnecessary */
/* vertical-align: middle; <-- remove; unnecessary */
}
<div class="container">
<div class="item">
<div class="item-inner">
<a>Button</a>
</div>
</div>
<div class="item">
<div class="item-inner">
<a>Button</a>
</div>
</div>
<div class="item">
<div class="item-inner">
<a>Button</a>
</div>
</div>
</div>
jsFiddle demo
Spiegazione
Il mio problema è che .item-inner { height: 100% }non funziona in webkit (Chrome).
Non funziona perché stai utilizzando l'altezza percentuale in un modo non conforme all'implementazione tradizionale delle specifiche.
10.5 Altezza del contenuto: la heightproprietà
percentuale
Specifica un'altezza percentuale. La percentuale viene calcolata rispetto all'altezza del blocco contenitore della casella generata. Se l'altezza del blocco contenitore non è specificata in modo esplicito e questo elemento non è posizionato in modo assoluto, il valore viene calcolato su auto.
auto
L'altezza dipende dai valori di altre proprietà.
In altre parole, affinché l'altezza percentuale funzioni su un figlio in-flow, il genitore deve avere un'altezza impostata.
Nel tuo codice, il contenitore di livello superiore ha un'altezza definita: .container { height: 20em; }
Il contenitore di terzo livello ha un'altezza definita: .item-inner { height: 100%; }
Ma tra loro, il contenitore di secondo livello - .item- no ha un'altezza definita. Webkit lo considera come un collegamento mancante.
.item-innersta dicendo a Chrome: dammiheight: 100% . Chrome guarda al genitore ( .item) come riferimento e risponde: il 100% di cosa? Non vedo nulla (ignorando la flex: 1regola che c'è). Di conseguenza, si applica height: auto(altezza del contenuto), in conformità con le specifiche.
Firefox, d'altra parte, ora accetta l'altezza di flessione di un genitore come riferimento per l'altezza percentuale del bambino. IE11 e Edge accettano anche altezze di flessione.
Inoltre, Chrome accetterà flex-growcome riferimento padre adeguato se utilizzato insieme aflex-basis (qualsiasi valore numerico funziona ( autonon funzionerà), incluso flex-basis: 0). Al momento della stesura di questo documento, tuttavia, questa soluzione non funziona in Safari.
#outer {
display: flex;
flex-direction: column;
height: 300px;
background-color: white;
border: 1px solid red;
}
#middle {
flex-grow: 1;
flex-basis: 1px;
background-color: yellow;
}
#inner {
height: 100%;
background-color: lightgreen;
}
<div id="outer">
<div id="middle">
<div id="inner">
INNER
</div>
</div>
</div>
Quattro soluzioni
1. Specificare un'altezza su tutti gli elementi padre
Una soluzione affidabile per più browser consiste nello specificare un'altezza su tutti gli elementi padre. Ciò impedisce collegamenti mancanti, che i browser basati su Webkit considerano una violazione delle specifiche.
Si noti che min-heighte max-heightnon sono accettabili. Deve essere la heightproprietà.
Maggiori dettagli qui: utilizzo della heightproprietà CSS e dei valori percentuali
2. Posizionamento relativo e assoluto CSS
Applicare position: relativeal genitore e position: absoluteal bambino.
Taglia il bambino con height: 100%e width: 100%, o utilizzare le proprietà di offset: top: 0, right: 0, bottom: 0, left: 0.
Con il posizionamento assoluto, l'altezza percentuale funziona senza un'altezza specificata sul genitore.
3. Rimuovere contenitori HTML non necessari (consigliato)
C'è bisogno di due container in giro button? Perché non rimuovere .itemo .item-inner, o entrambi? Sebbene gli buttonelementi a volte falliscano come contenitori flessibili , possono essere oggetti flessibili. Prendi in considerazione l'idea di creare buttonun figlio .containero di .itemrimuovere un markup gratuito.
Ecco un esempio:
.container {
height: 20em;
display: flex;
flex-direction: column;
border: 5px solid black
}
a {
flex: 1;
background: orange;
border-bottom: 1px solid white;
display: flex; /* nested flex container (for aligning text) */
align-items: center; /* center text vertically */
justify-content: center; /* center text horizontally */
}
<div class="container">
<a>Button</a>
<a>Button</a>
<a>Button</a>
</div>
4. Contenitori Flex nidificati (consigliato)
Sbarazzarsi delle altezze percentuali. Sbarazzarsi delle proprietà della tabella. Sbarazzarsi di vertical-align. Evitare il posizionamento assoluto. Attacca con flexbox fino in fondo.
Applicare display: flexsull'elemento flessibile ( .item), rendendolo un contenitore flessibile. Questo imposta automaticamente align-items: stretch, che dice al bambino ( .item-inner) di espandere l'intera altezza del genitore.
Importante: rimuovere le altezze specificate dagli oggetti flessibili per far funzionare questo metodo. Se un bambino ha un'altezza specificata (ad es. height: 100%), Ignorerà la align-items: stretchprovenienza dal genitore. Perché l' stretchimpostazione predefinita funzioni, è necessario calcolare l'altezza del bambino auto (spiegazione completa ).
Prova questo (nessuna modifica a HTML):
.container {
display: flex;
flex-direction: column;
height: 20em;
border: 5px solid black
}
.item {
display: flex; /* new; nested flex container */
flex: 1;
border-bottom: 1px solid white;
}
.item-inner {
display: flex; /* new; nested flex container */
flex: 1; /* new */
/* height: 100%; <-- remove; unnecessary */
/* width: 100%; <-- remove; unnecessary */
/* display: table; <-- remove; unnecessary */
}
a {
display: flex; /* new; nested flex container */
flex: 1; /* new */
align-items: center; /* new; vertically center text */
background: orange;
/* display: table-cell; <-- remove; unnecessary */
/* vertical-align: middle; <-- remove; unnecessary */
}
<div class="container">
<div class="item">
<div class="item-inner">
<a>Button</a>
</div>
</div>
<div class="item">
<div class="item-inner">
<a>Button</a>
</div>
</div>
<div class="item">
<div class="item-inner">
<a>Button</a>
</div>
</div>
</div>