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: flex
sull'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: stretch
provenienza dal genitore. Perché l' stretch
impostazione 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 height
proprietà
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-inner
sta dicendo a Chrome: dammiheight: 100%
. Chrome guarda al genitore ( .item
) come riferimento e risponde: il 100% di cosa? Non vedo nulla (ignorando la flex: 1
regola 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-grow
come riferimento padre adeguato se utilizzato insieme aflex-basis
(qualsiasi valore numerico funziona ( auto
non 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-height
e max-height
non sono accettabili. Deve essere la height
proprietà.
Maggiori dettagli qui: utilizzo della height
proprietà CSS e dei valori percentuali
2. Posizionamento relativo e assoluto CSS
Applicare position: relative
al genitore e position: absolute
al 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 .item
o .item-inner
, o entrambi? Sebbene gli button
elementi a volte falliscano come contenitori flessibili , possono essere oggetti flessibili. Prendi in considerazione l'idea di creare button
un figlio .container
o di .item
rimuovere 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: flex
sull'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: stretch
provenienza dal genitore. Perché l' stretch
impostazione 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>