Flexbox

The CSS Podcast - 010: Flexbox

Un pattern di design che può essere complicato nel responsive design è una barra laterale in linea con alcuni contenuti. Se c'è spazio dell'area visibile, questo pattern funziona molto bene, ma se lo spazio è ridotto, il layout rigido può diventare problematico.

Il modello di layout a riquadri flessibili (flexbox) è un modello di layout progettato per contenuti unidimensionali. È particolarmente adatto a gestire una serie di elementi di dimensioni diverse e a restituire il layout migliore per questi elementi.

Questo è il modello di layout ideale per questo modello di barra laterale. Flexbox non solo aiuta a disporre la barra laterale e i contenuti in linea, ma, se lo spazio rimanente non è sufficiente, la barra laterale viene interrotta in una nuova riga. Invece di impostare dimensioni rigide che il browser dovrà seguire, con flexbox puoi fornire confini flessibili per suggerire in che modo potrebbero essere visualizzati i contenuti.

Che cosa puoi fare con un layout flessibile?

I layout flessibili hanno le seguenti funzionalità, che potrai esplorare in questa guida.

  • Possono essere visualizzati come riga o colonna.
  • Rispettano la modalità di scrittura del documento.
  • Sono a riga singola per impostazione predefinita, ma è possibile chiedere di andare a capo su più righe.
  • Gli elementi del layout possono essere riordinati visivamente, diversamente dall'ordine nel DOM.
  • Lo spazio può essere distribuito all'interno degli elementi, in modo che diventino più grandi e più piccoli a seconda dello spazio disponibile nell'elemento principale.
  • Lo spazio può essere distribuito intorno agli elementi e alle linee flessibili in un layout aggregato utilizzando le proprietà di Allineamento riquadri.
  • Gli elementi stessi possono essere allineati sull'asse trasversale.

L'asse principale e l'asse trasversale

La chiave per comprendere flexbox è il concetto di asse principale e asse trasversale. L'asse principale è quello impostato dalla proprietà flex-direction. Se è row, l'asse principale è lungo la riga, mentre se è column, l'asse principale è lungo la colonna.

Tre riquadri uno accanto all'altro con una freccia, che puntano da sinistra a destra. La freccia è contrassegnata come Asse principale

Gli elementi flessibili si spostano come gruppo sull'asse principale. Ricorda: abbiamo un sacco di elementi e stiamo cercando di trovare il layout migliore per il gruppo.

L'asse secondario è disposto nella direzione opposta all'asse principale, quindi se flex-direction è row, l'asse secondario è disposto lungo la colonna.

Tre caselle di altezze diverse, una accanto all'altra, con una freccia rivolta da sinistra a destra. La freccia è etichettata come Asse principale. C'è un'altra freccia rivolta dall'alto verso il basso. Questa è etichettata come Asse trasversale

Puoi eseguire due operazioni sull'asse trasversale. Puoi spostare gli elementi singolarmente o come gruppo in modo che siano allineati tra loro e al contenitore flessibile. Inoltre, se hai linee flessibili con a capo, puoi trattarle come un gruppo per controllare la modalità di assegnazione dello spazio a queste linee. Vedrai come funziona tutto nella pratica nel corso di questa guida. Per il momento, tieni presente che l'asse principale segue il tuo flex-direction.

Creazione di un contenitore flessibile

Vediamo come si comporta flexbox prendendo un gruppo di elementi di dimensioni diverse e utilizzandolo per la loro impaginazione.

<div class="container" id="container">
  <div>One</div>
  <div>Item two</div>
  <div>The item we will refer to as three</div>
</div>

Per utilizzare flexbox, devi dichiarare che vuoi utilizzare un contesto di formattazione flessibile e non il layout in blocco e in linea normale. A tal fine, modifica il valore della proprietà display in flex.

.container {
  display: flex;
}

Come hai appreso nella guida al layout, otterrai una casella a livello di blocco con elementi flessibili secondari. Gli elementi flessibili iniziano immediatamente a mostrare alcuni comportamenti di flexbox, utilizzando i relativi valori iniziali.

I valori iniziali indicano che:

  • Gli elementi vengono visualizzati come una riga.
  • Non si avvolgono.
  • Non crescono fino a riempire il contenitore.
  • Si allineano all'inizio del contenitore.

Controllo della direzione degli elementi

Anche se non hai ancora aggiunto una proprietà flex-direction, gli elementi vengono visualizzati come riga perché il valore iniziale di flex-direction è row. Se vuoi una riga, non è necessario aggiungere la proprietà. Per modificare la direzione, aggiungi la proprietà e uno dei quattro valori:

  • row: gli elementi vengono disposti in una riga.
  • row-reverse: gli elementi sono disposti in una riga a partire dalla fine del container flessibile.
  • column: gli elementi vengono disposti in una colonna.
  • column-reverse: gli elementi vengono disposti in una colonna dalla fine del contenitore flessibile.

Puoi provare tutti i valori utilizzando il gruppo di elementi nella demo qui sotto.

Invertire il flusso degli elementi e l'accessibilità

Bisogna fare attenzione quando si utilizzano proprietà che riordinano la visualizzazione visiva distinta da come sono ordinati gli elementi nel documento HTML, poiché ciò potrebbe influire negativamente sull'accessibilità. I valori row-reverse e column-reverse sono un buon esempio di questo. Il riordinamento avviene solo per l'ordine visivo, non per quello logico. Questo è importante da capire perché l'ordine logico è l'ordine con cui uno screen reader leggerà i contenuti e chiunque si muova usando la tastiera seguirà.

Nel video che segue puoi vedere come, in un layout di righe invertite, le schede tra i link vengono disconnesse quando la navigazione da tastiera segue il DOM, non la visualizzazione grafica.

Tutto ciò che può modificare l'ordine degli elementi in flexbox o nella griglia può causare questo problema. Pertanto, il riordinamento deve includere dei test accurati per verificare che non comprometta l'utilizzo del sito per alcune persone.

Per ulteriori informazioni, consulta:

Modalità di scrittura e direzione

Per impostazione predefinita, gli elementi flessibili vengono disposti in una riga. Una riga viene visualizzata nella direzione in cui scorrono le frasi nella modalità di scrittura e nella direzione dello script. Ciò significa che se lavori in arabo, che ha una direzione di script da destra a sinistra (rtl), gli elementi verranno allineati sulla destra. Anche l'ordine delle tabulazioni inizierà a destra, perché è così che vengono lette le frasi in arabo.

Se utilizzi una modalità di scrittura verticale, come alcuni caratteri giapponesi, una riga verrà visualizzata verticalmente, dall'alto verso il basso. Prova a cambiare flex-direction in questa demo che utilizza una modalità di scrittura verticale.

Di conseguenza, il comportamento predefinito degli elementi flessibili è collegato alla modalità di scrittura del documento. La maggior parte dei tutorial è scritta in inglese o in un'altra modalità di scrittura orizzontale da sinistra verso destra. In questo modo, è facile presumere che gli elementi flessibili siano allineati a sinistra e vengano visualizzati orizzontalmente.

Considerando gli assi principali e trasversali più la modalità di scrittura da considerare, il fatto che parliamo di start e end anziché di top, basso, sinistra e destra in flexbox potrebbe essere più facile da capire. Ogni asse ha un inizio e una fine. L'inizio dell'asse principale è indicato come main-start. Pertanto, i nostri elementi flessibili si allineano inizialmente da main-start. La fine di questo asse è main-end. L'inizio dell'asse trasversale è cross-start e la fine cross-end.

Un diagramma con etichette dei termini precedenti

Aggregazione di elementi flex

Il valore iniziale della proprietà flex-wrap è nowrap. Ciò significa che se non c'è spazio sufficiente nel contenitore, gli elementi andranno in overflow.

Un contenitore flessibile con nove elementi al suo interno. Gli elementi sono stati ridotti in modo che una parola sia su una riga, ma non c&#39;è spazio sufficiente per mostrarli uno accanto all&#39;altro, quindi gli elementi flessibili si sono estesi al di fuori della casella del contenitore.
Una volta raggiunte le dimensioni minime dei contenuti, gli elementi flessibili inizieranno a sovraccaricare il container

Gli elementi visualizzati utilizzando i valori iniziali verranno ridotti al minimo, fino alla dimensione min-content, prima che si verifichi il sovraccarico.

Per far sì che gli elementi vengano a capo, aggiungi flex-wrap: wrap al contenitore flessibile.

.container {
  display: flex;
  flex-wrap: wrap;
}

Quando un contenitore flessibile viene agganciato, vengono create più linee flessibili. In termini di distribuzione dello spazio, ogni riga si comporta come un nuovo contenitore flessibile. Pertanto, se inserisci un a capo nelle righe, non è possibile allineare un elemento nella riga 2 con un elemento sopra di essa nella riga 1. Questo è il significato di "flexbox è unidimensionale". Puoi controllare l'allineamento su un solo asse, una riga o una colonna, non entrambi insieme come facciamo in una griglia.

La notazione abbreviata per il flusso flessibile

Puoi impostare le proprietà flex-direction e flex-wrap utilizzando la forma abbreviata flex-flow. Ad esempio, per impostare flex-direction su column e consentire il rientro degli elementi:

.container {
  display: flex;
  flex-flow: column wrap;
}

Controllo dello spazio all'interno degli elementi flessibili

Supponendo che il contenitore abbia più spazio del necessario per visualizzare gli elementi, gli elementi si allineano all'inizio e non aumentano per riempire lo spazio. Smettono di crescere quando raggiungono le dimensioni massime dei contenuti. Questo perché il valore iniziale delle proprietà flex- è:

  • flex-grow: 0: gli elementi non aumentano.
  • flex-shrink: 1: gli articoli possono restringersi più del loro flex-basis.
  • flex-basis: auto: gli articoli hanno una dimensione di base di auto.

Questo può essere rappresentato da un valore della parola chiave flex: initial. La proprietà abbreviata flex o le versioni complete di flex-grow, flex-shrink e flex-basis vengono applicate agli elementi secondari del contenitore flex.

Per far crescere gli elementi e lasciare spazio a quelli più grandi rispetto a quelli piccoli, usa flex:auto. Puoi provare questa funzionalità utilizzando la demo qui sopra. Le proprietà vengono impostate su:

  • flex-grow: 1: gli elementi possono diventare più grandi di flex-basis.
  • flex-shrink: 1: gli articoli possono restringersi più del loro flex-basis.
  • flex-basis: auto: gli elementi hanno una dimensione di base pari a auto.

Se utilizzi flex: auto, gli elementi avranno dimensioni diverse, poiché lo spazio condiviso tra loro viene condiviso dopo che ogni elemento è stato impostato come dimensione massima dei contenuti. Pertanto, un elemento di grandi dimensioni occuperà più spazio. Per forzare tutti gli elementi a avere dimensioni coerenti e ignorare le dimensioni dei contenuti, imposta flex:auto su flex: 1 nella demo.

che si separa in:

  • flex-grow: 1: gli elementi possono diventare più grandi del loro flex-basis.
  • flex-shrink: 1: gli elementi possono restringersi meno del relativo flex-basis.
  • flex-basis: 0: gli articoli hanno una dimensione di base di 0.

L'uso di flex: 1 indica che tutti gli elementi hanno dimensioni pari a zero, quindi tutto lo spazio nel container flessibile è disponibile per essere distribuito. Poiché tutti gli elementi hanno un fattore di flex-grow pari a 1, crescono tutti in modo uguale e lo spazio viene condiviso in modo uguale.

Consentire la crescita degli articoli a tassi diversi

Non è necessario assegnare a tutti gli elementi un fattore di flex-grow pari a 1. Puoi assegnare fattori flex-grow diversi agli elementi flessibili. Nella demo sotto il primo elemento ha flex: 1, il secondo flex: 2 e il terzo flex: 3. Quando questi elementi aumentano da 0, lo spazio disponibile nel contenitore flessibile viene suddiviso in sei. Una parte viene assegnata al primo elemento, due parti al secondo, tre parti al terzo.

Puoi fare la stessa cosa da un elemento flex-basis di auto, ma devi specificare i tre valori. Il primo valore è flex-grow, il secondo flex-shrink e il terzo flex-basis.

.item1 {
  flex: 1 1 auto;
}

.item2 {
  flex: 2 1 auto;
}

Si tratta di un caso d'uso meno comune, in quanto il motivo per cui utilizzare un flex-basis di auto è consentire al browser di capire la distribuzione dello spazio. Se vuoi che un elemento aumenti un po' di più rispetto a quanto stabilito dall'algoritmo, tuttavia, potrebbe essere utile.

Riordinare gli elementi flessibili

Gli elementi del contenitore flessibile possono essere riordinati utilizzando la proprietà order. Questa proprietà consente di ordinare gli elementi in gruppi ordinali. Gli elementi vengono disposti nella direzione dettata da flex-direction, prima i valori più bassi. Se più elementi hanno lo stesso valore, questo verrà visualizzato con gli altri elementi con lo stesso valore.

L'esempio seguente mostra questo ordinamento.

Verificare di aver compreso

Metti alla prova le tue conoscenze su flexbox

Il valore predefinito di flex-direction è

row
Per impostazione predefinita, flexbox inserisce gli elementi in una riga, allineandoli all'inizio. Quando il wrapping è attivo, continuerà a creare righe in cui gli elementi secondari possono scorrere.
column
L'impostazione di flex-direction su colonna è un ottimo modo per impilare gli elementi, ma non è il valore predefinito.

Per impostazione predefinita, un contenitore flessibile aggrega gli elementi secondari.

true
Il wrapping deve essere abilitato.
falso
Usa flex-wrap: wrap con display: flex per aggregare elementi secondari

Un elemento secondario flex appare schiacciato. Quale proprietà flex aiuta a mitigare questo problema?

flex-grow
Questa proprietà descrive se gli elementi possono crescere oltre una dimensione base, non come dovrebbero comportarsi in base a una determinata dimensione.
flex-shrink
Sì, questa proprietà descrive come gestire le dimensioni se la larghezza è inferiore alla base.
flex-basis
Questo fornisce il punto di partenza per le dimensioni, ma non spiega come gestire gli scenari di dimensionamento in cui la larghezza è inferiore a quella di base, ad esempio in uno scenario compresso.

Panoramica dell'allineamento a Flexbox

Flexbox ha fornito una serie di proprietà per l'allineamento degli elementi e la distribuzione di spazio tra gli elementi. Queste proprietà sono state così utili che sono state spostate in una specifica a parte e le troverai anche nel layout a griglia. Qui puoi scoprire come funzionano quando utilizzi flexbox.

L'insieme di proprietà può essere suddiviso in due gruppi. Proprietà di distribuzione degli spazi e proprietà di allineamento. Le proprietà che distribuiscono lo spazio sono:

  • justify-content: distribuzione degli spazi sull'asse principale.
  • align-content: distribuzione dello spazio sull'asse trasversale.
  • place-content: una forma abbreviata per impostare entrambe le proprietà menzionate sopra.

Le proprietà utilizzate per l'allineamento in flexbox:

  • align-self: consente di allineare un singolo elemento sull'asse trasversale.
  • align-items: allinea tutti gli elementi come gruppo sull'asse trasversale.

Se stai lavorando sull'asse principale, le proprietà iniziano con justify-. Sull'asse trasversale iniziano con align-.

Distribuzione dello spazio sull'asse principale

Con il codice HTML utilizzato in precedenza, gli elementi flessibili disposti in una riga lasciano spazio sull'asse principale. Gli elementi non sono abbastanza grandi da riempire completamente il contenitore flessibile. Gli elementi vengono visualizzati all'inizio del container flessibile perché il valore iniziale di justify-content è flex-start. Gli elementi sono allineati all'inizio e gli spazi aggiuntivi sono alla fine.

Aggiungi la proprietà justify-content al contenitore flessibile, assegnale un valore di flex-end, e gli elementi si allineano alla fine del contenitore e lo spazio rimanente viene posizionato all'inizio.

.container {
  display: flex;
  justify-content: flex-end;
}

Puoi anche distribuire lo spazio tra gli elementi con justify-content: space-between.

Prova alcuni dei valori nella demo e consulta MDN per l'insieme completo di valori possibili.

Con flex-direction: column

Se hai modificato flex-direction in column, justify-content funzionerà nella colonna. Per avere spazio libero nel contenitore quando lavori come colonna, devi assegnare al contenitore un height o un block-size. In caso contrario, non avrai spazio libero da distribuire.

Prova i diversi valori, questa volta con un layout a colonne flexbox.

Distribuzione dello spazio tra le righe flessibili

Con un container flessibile aggregato, potresti avere spazio da distribuire sull'asse trasversale. In questo caso puoi utilizzare la proprietà align-content con gli stessi valori di justify-content. A differenza di justify-content, che allinea gli elementi a flex-start per impostazione predefinita, align-content ha un valore iniziale pari a stretch. Aggiungi la proprietà align-content al contenitore flessibile per modificare questo comportamento predefinito.

.container {
  align-content: center;
}

Prova questa funzionalità nella demo. L'esempio contiene righe di elementi flessibili con a capo e il contenitore ha un block-size per avere spazio libero.

La grafia abbreviata di place-content

Per impostare sia justify-content che align-content, puoi utilizzare place-content con uno o due valori. Verrà utilizzato un unico valore per entrambi gli assi se specifichi entrambi, il primo per align-content e il secondo per justify-content.

.container {
  place-content: space-between;
  /* sets both to space-between */
}

.container {
  place-content: center flex-end;
  /* wrapped lines on the cross axis are centered,
  on the main axis items are aligned to the end of the flex container */
}

Allineamento degli elementi sull'asse trasversale

Nell'asse trasversale puoi anche allineare gli elementi all'interno della riga flessibile utilizzando align-items e align-self. Lo spazio disponibile per questo allineamento dipenderà dall'altezza del container flessibile o dalla linea flessibile nel caso di un insieme di elementi aggregati.

Il valore iniziale di align-self è stretch, motivo per cui gli elementi flessibili in una riga si estendono fino all'altezza dell'elemento più alto per impostazione predefinita. Per modificare questo valore, aggiungi la proprietà align-self a uno degli elementi flessibili.

.container {
  display: flex;
}

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

Utilizza uno dei seguenti valori per allineare l'elemento:

  • flex-start
  • flex-end
  • center
  • stretch
  • baseline

Consulta l'elenco completo dei valori su MDN.

La demo successiva ha una singola riga di elementi flessibili con flex-direction: row. L'ultimo elemento definisce l'altezza del contenitore flessibile. Il primo elemento ha la proprietà align-self con un valore flex-start. Prova a modificare il valore di quella proprietà per vedere come si sposta all'interno del suo spazio sull'asse trasversale.

La proprietà align-self viene applicata ai singoli elementi. La proprietà align-items può essere applicata al contenitore flessibile per impostare tutte le singole proprietà align-self come gruppo.

.container {
  display: flex;
  align-items: flex-start;
}

In questa demo successiva, prova a modificare il valore di align-items per allineare tutti gli elementi sull'asse trasversale come gruppo.

Perché non c'è la giustificazione in flexbox?

Gli elementi flessibili agiscono come un gruppo sull'asse principale. Pertanto, non esiste il concetto di suddividere un singolo elemento da questo gruppo.

Nel layout a griglia, le proprietà justify-self e justify-items agiscono sull'asse in linea per allineare gli elementi su quell'asse all'interno dell'area della griglia. A causa del modo in cui i layout flessibili trattano gli elementi come un gruppo, queste proprietà non sono implementate in un contesto flessibile.

Vale la pena sapere che flexbox funziona molto bene con i margini automatici. Se devi separare un elemento da un gruppo o suddividere il gruppo in due, puoi applicare un margine. Nell'esempio seguente, l'ultimo elemento ha un margine sinistro di auto. Il margine automatico assorbe tutto lo spazio nella direzione in cui viene applicato. Ciò significa che sposta l'elemento verso destra, suddividendo i gruppi.

Come centrare un elemento verticalmente e orizzontalmente

Le proprietà di allineamento possono essere utilizzate per centrare un elemento all'interno di un'altra casella. La proprietà justify-content allinea l'elemento sull'asse principale, ovvero la riga. La proprietà align-items sull'asse trasversale.

.container {
  width: 400px;
  height: 300px;
  display: flex;
  justify-content: center;
  align-items: center;
}

Verifica le tue conoscenze

Metti alla prova le tue conoscenze su flexbox

.container {
  display: flex;
  direction: ltr;
}

Per allineare verticalmente con flexbox, utilizza

allinea parole chiave
Incredibile
giustifica le parole chiave
Spiacenti
.container {
  display: flex;
  direction: ltr;
}

Per allinearlo orizzontalmente a flexbox, utilizza

parole chiave in linea
Spiacenti
giustificare le parole chiave
Incredibile
.container {
  display: flex;
  direction: ltr;
}

Per impostazione predefinita, gli elementi flessibili sono allineati a stretch. Se vuoi che la dimensione dei contenuti venga utilizzata per gli elementi secondari, quale dei seguenti stili utilizzerai?

justify-content: flex-start
La proprietà justify è per l'allineamento orizzontale, non verticale.
align-content: start
content allinea le righe flessibili, non l'allineamento degli elementi figlio.
height: auto
Questa operazione non avrà alcun effetto.
align-items: flex-start
Sì, vogliamo allinearli verticalmente a "top" o all'inizio, il che rimuove il valore di allungamento predefinito e utilizza invece l'altezza dei contenuti.

Risorse