Cosa fa display: flex
Metti display: flex su un genitore e i suoi figli diretti si allineano in una riga, uno accanto all'altro, e si allungano alla stessa altezza. Quella sola dichiarazione sostituisce float, inline-block e la maggior parte dei trucchi di posizionamento per disporre una fila di cose.
Nel primo box ogni div occupa una riga intera. Nel secondo i tre elementi stanno in una riga, ognuno largo solo quanto il suo contenuto, e One e Three si allungano fino all'altezza di Two. È cambiato solo il genitore: display: flex va sul contenitore, mai sugli elementi.
Playground flexbox
Scegli dei valori e guarda gli elementi muoversi. La riga di codice sotto il box è il CSS di ciò che vedi, e l'elenco sotto è dove il browser ha effettivamente collocato ogni elemento, misurato con getBoundingClientRect().
Cose da provare:
justify-content: space-between: l'elemento 1 finisce a x 0 e l'elemento 3 tocca il bordo opposto.align-items: center: i tre elementi mantengono la propria altezza e i loro centri si allineano. Con il valore predefinitostretch, l'elemento 1 non ha un'altezza propria e riempie tutti i 170px del contenitore.flex-direction: column: orajustify-contentsposta gli elementi in verticale ealign-itemsin orizzontale. Le due proprietà seguono gli assi, non lo schermo.
Asse principale e asse trasversale
Ogni contenitore flex ha due assi. L'asse principale è la direzione in cui scorrono gli elementi, impostata da flex-direction. L'asse trasversale lo attraversa.
flex-direction | Asse principale | Asse trasversale | justify-content sposta gli elementi | align-items sposta gli elementi |
|---|---|---|---|---|
row (predefinito) | orizzontale, nell'ordine di lettura | verticale | in orizzontale | in verticale |
row-reverse | orizzontale, al contrario | verticale | in orizzontale | in verticale |
column | verticale, dall'alto in basso | orizzontale | in verticale | in orizzontale |
column-reverse | verticale, dal basso in alto | orizzontale | in verticale | in orizzontale |
In una pagina da destra a sinistra (dir="rtl"), row parte dal bordo destro, perché l'asse principale segue la direzione di scrittura.
Proprietà del contenitore
Queste vanno sull'elemento con display: flex:
| Proprietà | Cosa fa | Predefinito |
|---|---|---|
flex-direction | Riga o colonna, e in che verso | row |
flex-wrap | Se gli elementi passano a una nuova riga quando finisce lo spazio | nowrap |
flex-flow | Forma abbreviata per flex-direction e flex-wrap | row nowrap |
justify-content | Posizione e spaziatura lungo l'asse principale | normal (si comporta come flex-start) |
align-items | Posizione degli elementi lungo l'asse trasversale | normal (si comporta come stretch) |
align-content | Spaziatura tra le righe quando gli elementi vanno a capo | normal |
gap | Spazio tra gli elementi (row-gap, column-gap) | 0 |
justify-content e align-items hanno ciascuna una pagina con tutti i valori: justify-content e align-items. L'andata a capo e la direzione sono nella pagina su flex-wrap.
Proprietà degli elementi: flex-grow, flex-shrink, flex-basis
Queste vanno sui figli e decidono come si dividono la larghezza del contenitore:
flex-basis: la dimensione da cui parte un elemento prima che lo spazio libero venga distribuito (autosignifica "usa la mia larghezza o il mio contenuto").flex-grow: quante quote dello spazio avanzato prende l'elemento.0significa che non cresce mai.flex-shrink: quanto cede l'elemento quando lo spazio non basta.0significa che non si restringe mai.
La forma abbreviata flex le imposta tutte e tre:
| Scrivi | Che significa | Comportamento |
|---|---|---|
flex: initial (predefinito) | 0 1 auto | Dimensione del contenuto, può restringersi, non cresce mai |
flex: 1 | 1 1 0% | Parte da zero e prende una quota uguale dello spazio |
flex: auto | 1 1 auto | Dimensione del contenuto più una quota dello spazio avanzato |
flex: none | 0 0 auto | Esattamente il suo contenuto o la sua larghezza, non cresce né si restringe mai |
flex: 2 | 2 1 0% | Il doppio della quota di un elemento con flex: 1 |
Ogni riga è larga 480px dentro il suo padding, e i due spazi da 8px lasciano 464px per gli elementi. Le larghezze stampate mostrano come è stato diviso: circa 155px ciascuno nella prima riga, 116 + 232 + 116 nella seconda (l'elemento con flex: 2 riceve il doppio della quota di ciascun vicino), e 100 + 372 nella terza, dove l'elemento con flex: none mantiene la sua larghezza e l'altro prende tutto il resto.
Layout reali con flexbox
Un header con un logo all'inizio e i link alla fine è il layout flex più comune. margin-inline-start: auto su un elemento si mangia tutto lo spazio libero prima di sé e spinge alla fine sia l'elemento sia tutto ciò che lo segue:
align-items: center allinea il testo più grande del logo con i link, e gap spazia i link senza margini da annullare sull'ultimo.
Un secondo schema quotidiano è la riga media: un'icona a dimensione fissa e un testo che prende il resto e va a capo nella sua colonna.
flex: none è la garanzia. Gli elementi flex si restringono per impostazione predefinita, quindi se lo togli dal cerchio e togli anche flex: 1 dal testo, il paragrafo schiaccia il cerchio fino a circa 23px di larghezza: un ovale. Per centrare una cosa in un box, con flexbox bastano due righe (justify-content: center; align-items: center); la pagina su come centrare un div lo confronta con gli altri metodi.
order e accessibilità
La proprietà order e le direzioni -reverse cambiano dove gli elementi appaiono, non dove si trovano nell'HTML. Gli screen reader e il tasto Tab seguono comunque l'ordine dell'HTML, quindi chi usa la tastiera può saltare dal primo link sullo schermo all'ultimo. Usali solo per decorazione; quando l'ordine ha un significato, cambia l'HTML.
Flexbox o grid
Flexbox lavora in una direzione alla volta: gli elementi in una riga si dimensionano in base al contenuto, e una seconda riga (con l'andata a capo) non si allinea con la prima. Grid lavora in due: definisci colonne e righe e gli elementi ci si incastrano. Una barra di navigazione, una toolbar o una riga di un modulo sono flexbox; una galleria o una pagina con barra laterale sono grid.
Errori comuni
display: flexsull'elemento invece che sul genitore. Il contenitore ricevedisplay: flex; i suoi figli sono gli elementi.- Aspettarsi che
align-itemssposti gli elementi in verticale senza altezza. Se il contenitore è alto solo quanto il suo elemento più alto, non c'è spazio per spostarli. Dai un'altezza al contenitore, oppure sta funzionando e semplicemente non ha nulla da fare. - Testo che esce invece di restringersi. Gli elementi flex hanno
min-width: auto. Aggiungimin-width: 0all'elemento che deve restringersi. - Usare
flex: 1e chiedersi perché le larghezze sono diverse. Gli elementi conflex: 1si dividono lo spazio in parti uguali, ma un elemento il cui contenuto non ci sta (un URL lungo, un'immagine) non si restringe al di sotto. Anche qui la soluzione èmin-width: 0. - Margini tra gli elementi. Usa
gapsul contenitore; va solo tra gli elementi. - Annidare flex senza motivo. Solo i figli diretti sono elementi flex. I nipoti seguono il layout normale, a meno che anche il loro genitore non abbia
display: flex.
Domande frequenti
Cosa fa display: flex?
Trasforma un elemento in un contenitore flex. I suoi figli diretti diventano elementi flex e per impostazione predefinita vengono messi in riga, uno accanto all'altro, allungati alla stessa altezza, con proprietà come justify-content, align-items e gap che controllano come si dividono lo spazio.
Cosa significa flex: 1?
flex: 1 è la forma breve di flex: 1 1 0%: l'elemento può crescere (flex-grow: 1), può restringersi (flex-shrink: 1) e parte da una dimensione zero (flex-basis: 0%). Gli elementi che hanno tutti flex: 1 si dividono lo spazio libero in parti uguali, quindi finiscono per avere la stessa larghezza, a meno che il loro contenuto non ci stia.
Che differenza c'è tra justify-content e align-items?
justify-content posiziona gli elementi lungo l'asse principale (in orizzontale in una riga), e align-items lungo l'asse trasversale (in verticale in una riga). Con flex-direction: column i due assi si scambiano, quindi justify-content diventa verticale.
Meglio flexbox o grid?
Usa flexbox per una sola riga o colonna i cui elementi si dimensionano in base al contenuto: barre di navigazione, gruppi di pulsanti, un'etichetta accanto a un input. Usa grid quando vuoi righe e colonne allineate tra loro, come una griglia di schede o il layout di una pagina.
Perché il mio elemento flex esce dal contenitore?
Un elemento flex ha min-width: auto per impostazione predefinita, quindi si rifiuta di restringersi sotto la larghezza della sua parola più lunga o del suo figlio più largo. Imposta min-width: 0 (o overflow: hidden) sull'elemento per permettergli di restringersi, per esempio per far funzionare text-overflow: ellipsis.
Flexbox funziona su elementi inline come span?
Sì. Qualsiasi elemento con display: flex è un contenitore flex, e i suoi figli diventano elementi flex qualunque sia il loro display, quindi i figli <span> smettono di essere inline e accettano larghezza, altezza e margin come i blocchi.