Flexbox

Podcast su CSS - 010: Flexbox

Un pattern di progettazione che può essere difficoltoso nel Responsive Web Design è la barra laterale incorporata ad alcuni contenuti. Questo modello funziona molto bene nel caso dell'area visibile, ma quando lo spazio è condensato, il layout rigido può diventare problematico.

Il Modello di layout flessibile (flexbox) è un modello di layout progettato per contenuti unidimensionali. È particolarmente efficace nel selezionare una serie di articoli di dimensioni diverse e restituire il layout migliore per questi elementi.

È il modello di layout ideale per questo pattern della barra laterale. Flexbox non solo consente di disporre la barra laterale e i contenuti in linea, ma se non c'è abbastanza spazio, la barra laterale si sposta in una nuova riga. Invece di impostare dimensioni rigide da seguire per il browser, con flexbox, puoi fornire limiti flessibili per suggerire come 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.
  • Per impostazione predefinita sono costituite da una sola riga, ma è possibile aggregarli su più righe.
  • Gli elementi nel layout possono essere riordinati visivamente, lontano dal loro ordine nel DOM.
  • È possibile distribuire lo spazio all'interno degli elementi, in modo da ridurli sempre più in base allo spazio disponibile nell'elemento padre.
  • Lo spazio può essere distribuito intorno agli elementi e alle linee flessibili in un layout a capo, utilizzando le proprietà Allineamento riquadro.
  • Gli elementi stessi possono essere allineati sull'asse trasversale.

L'asse principale e l'asse trasversale

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

Tre caselle una accanto all'altra con una freccia, che punta da sinistra a destra. La freccia è denominata Asse principale

Gli elementi flessibili si spostano come gruppo sull'asse principale. Ricorda: abbiamo molte cose e stiamo cercando di ottenere il layout migliore per loro come gruppo.

L'asse trasversale corre nell'altra direzione rispetto all'asse principale, quindi, se flex-direction è row, l'asse incrociato corre lungo la colonna.

Tre riquadri di diverse altezze, uno accanto all'altro con una freccia, che punta da sinistra a destra. La freccia è denominata Asse principale. C'è un'altra freccia che punta dall'alto verso il basso. Questa è etichettata Asse incrociato

Puoi eseguire due operazioni sull'asse trasversale. Puoi spostare gli elementi singolarmente o in gruppo in modo che siano allineati tra loro e con il contenitore flessibile. Inoltre, se hai linee flessibili aggregate, puoi trattarle come un gruppo per controllare l'assegnazione dello spazio a queste linee. In questa guida scoprirai come funziona in pratica. Per il momento tieni presente che l'asse principale segue flex-direction.

Creazione di un container flessibile

Vediamo come si comporta Flexbox prendendo un gruppo di elementi di dimensioni diverse e utilizzando flexbox per disporli.

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

Per usare Flexbox, devi dichiarare che vuoi usare un contesto di formattazione flessibile e non un layout standard e in blocco. Per farlo, 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 secondari flessibili. Gli elementi flessibili iniziano immediatamente a mostrare un determinato comportamento flexbox, utilizzando i relativi valori iniziali.

I valori iniziali indicano che:

  • Gli elementi vengono visualizzati come una riga.
  • Non vanno a capo.
  • Non crescono fino a riempire il contenitore.
  • Questi elementi vengono allineati all'inizio del container.

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 sono disposti in una riga.
  • row-reverse: gli elementi sono disposti come una riga dall'estremità del contenitore flessibile.
  • column: gli elementi sono disposti come una colonna.
  • column-reverse : gli elementi sono disposti come una colonna dall'estremità del contenitore flessibile.

Puoi provare tutti i valori utilizzando il gruppo di elementi della demo di seguito.

Invertire il flusso degli elementi e dell'accessibilità

Devi essere prudente quando utilizzi proprietà che riordinano la visualizzazione visiva lontano dall'ordine degli elementi nel documento HTML, poiché possono influire negativamente sull'accessibilità. I valori row-reverse e column-reverse sono un buon esempio. Il riordinamento avviene solo per l'ordine visivo, non per l'ordine logico. È importante capire questo aspetto perché l'ordine logico è l'ordine in cui uno screen reader leggerà i contenuti, dopodiché chiunque naviga utilizzando la tastiera.

Nel seguente video puoi vedere come, in un layout a riga invertita, il passaggio da un link all'altro si disconnette mentre la navigazione da tastiera segue il DOM e non la visualizzazione visiva.

Qualsiasi elemento che possa modificare l'ordine degli elementi in flexbox o griglia può causare questo problema. Pertanto, qualsiasi riordinamento deve includere test approfonditi per verificare che non rendano difficile l'utilizzo del tuo sito per alcune persone.

Per ulteriori informazioni, vedi:

Modalità e direzione di scrittura

Gli elementi flessibili vengono disposti come riga per impostazione predefinita. Una riga viene eseguita nella direzione in cui le frasi vanno nella modalità di scrittura e nella direzione dello script. Ciò significa che se lavori in arabo, la cui direzione dello script è da destra a sinistra (rtl), gli elementi verranno allineati a destra. L'ordine delle schede inizierà a destra, poiché questo è il modo in cui le frasi vengono lette in arabo.

Se lavori con una modalità di scrittura verticale, come alcuni caratteri giapponesi, una riga verrà eseguita in verticale, dall'alto verso il basso. In questa demo, prova a cambiare flex-direction, che utilizza una modalità di scrittura verticale.

Di conseguenza, il comportamento degli elementi flessibili per impostazione predefinita è collegato alla modalità di scrittura del documento. Quasi tutti i tutorial sono scritti in inglese o in un'altra modalità di scrittura orizzontale, da sinistra a destra. In questo modo si suppone facilmente che gli elementi flessibili vengano allineati a sinistra e vengano eseguiti orizzontalmente.

Considerando gli assi principale e trasversale, oltre alla modalità di scrittura da considerare, il fatto che in flexbox parliamo di start e end anziché di top, bottom, left e rightbox potrebbe essere più comprensibile. Ogni asse ha un inizio e una fine. L'inizio dell'asse principale è denominato avvio-principale. Quindi i nostri elementi flessibili inizialmente sono allineati dal principale. La fine di questo asse è main-end. L'inizio della croce è cross-start e la fine cross-end.

Diagramma etichettato dei termini riportati sopra

Aggregazione di elementi flessibili

Il valore iniziale della proprietà flex-wrap è nowrap. Ciò significa che se non c'è abbastanza spazio nel contenitore, gli elementi supereranno l'elenco.

Si tratta di un contenitore flessibile con nove elementi al suo interno, che si sono ridotti in modo che una parola sia su una riga, ma non c&#39;è abbastanza spazio per mostrarli uno accanto all&#39;altro, quindi gli elementi flessibili si sono estesi fuori dalla scatola del contenitore.
Una volta raggiunta la dimensione minima dei contenuti, gli elementi flessibili inizieranno a esaurire il contenitore

Gli elementi visualizzati utilizzando i valori iniziali verranno ridotti al minimo, fino alle dimensioni min-content prima che si verifichi l'overflow.

Per completare il wrapping degli elementi, aggiungi flex-wrap: wrap al contenitore flessibile.

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

Quando un contenitore flessibile viene a capo, crea più linee flessibili. In termini di distribuzione dello spazio, ogni riga funge da nuovo container flessibile. Pertanto, se stai eseguendo il wrapping di righe, non è possibile ottenere un elemento nella riga 2 da allineare con un elemento superiore nella riga 1. Questo è ciò che significa che gli annunci flexbox sono unidimensionali. Puoi controllare l'allineamento in un asse, in una riga o in una colonna, non in entrambi insieme come possiamo fare con la griglia.

La forma abbreviata "flex-flow"

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 l'aggregazione degli elementi:

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

Controllo dello spazio all'interno degli elementi flessibili

Se il contenitore ha più spazio di quello necessario per visualizzare gli elementi, questi vengono visualizzati all'inizio e non crescono fino a occupare lo spazio. e smettono di crescere raggiungendo le dimensioni massime dei contenuti. Questo perché il valore iniziale delle proprietà flex- è:

  • flex-grow: 0: gli elementi non ingrandiscono.
  • flex-shrink: 1: gli elementi possono ridurre le dimensioni di flex-basis.
  • flex-basis: auto: gli elementi hanno una dimensione di base pari a auto.

Può essere rappresentato da un valore della parola chiave pari a flex: initial. La proprietà abbreviata flex o i comandi lunghi di flex-grow, flex-shrink e flex-basis vengono applicati agli elementi secondari del contenitore flessibile.

Per far crescere gli elementi, lasciando più spazio a quelli di grandi dimensioni rispetto a quelli più piccoli, utilizza flex:auto. Puoi provare questa procedura utilizzando la demo in alto. In questo modo le proprietà vengono impostate su:

  • flex-grow: 1: gli elementi possono superare le dimensioni di flex-basis.
  • flex-shrink: 1: gli elementi possono ridurre le dimensioni di flex-basis.
  • flex-basis: auto: gli elementi hanno una dimensione di base pari a auto.

Se usi flex: auto, gli elementi avranno dimensioni diverse, poiché lo spazio condiviso tra loro viene condiviso dopo che ogni elemento è stato definito come dimensione massima dei contenuti. In questo modo, gli oggetti di grandi dimensioni occupano più spazio. Per forzare tutti gli elementi a avere una dimensione coerente e ignorare la dimensione della modifica dei contenuti flex:auto in flex: 1 nella demo.

Questo si decomprime in:

  • flex-grow: 1: gli elementi possono superare le dimensioni di flex-basis.
  • flex-shrink: 1: gli elementi possono ridurre le dimensioni di flex-basis.
  • flex-basis: 0: gli elementi hanno una dimensione di base pari a 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 flex-grow di 1, crescono tutti allo stesso modo e lo spazio viene condiviso equamente.

Consentire agli articoli di crescere a ritmi diversi

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

Puoi fare la stessa cosa da un flex-basis di auto, ma dovrai 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 utilizzare flex-basis di auto è consentire al browser di capire la distribuzione dello spazio. Se vuoi che un elemento cresca un po' di più rispetto a quanto decide l'algoritmo, ma potrebbe essere utile.

Riordinamento degli elementi flessibili

Gli elementi nel contenitore flessibile possono essere riordinati utilizzando la proprietà order. Questa proprietà consente di ordinare gli articoli nei gruppi ordinali. Gli elementi sono disposti nella direzione dettata da flex-direction, prima i valori più bassi. Se più elementi hanno lo stesso valore, verranno visualizzati insieme agli altri con quel valore.

L'esempio seguente mostra questo ordine.

Verifica la tua comprensione

Verifica le tue conoscenze su Flexbox

Il valore predefinito di flex-direction è

row
Per impostazione predefinita, Flexbox adatta gli elementi a una riga, allineandoli all'inizio. Con l'a capo attivato, continuerà a creare righe secondarie.
column
L'impostazione della direzione flessibile su colonna è un ottimo modo per sovrapporre gli elementi, ma non è il valore predefinito.

Per impostazione predefinita, un container flessibile esegue il wrapping degli elementi secondari.

true
L'aggregazione deve essere abilitata.
false
Usa flex-wrap: wrap con display: flex per inserire il codice per i bambini

Un elemento secondario flessibile sembra essere schiacciato. Quale proprietà flessibile aiuta a mitigare questo problema?

flex-grow
Questa proprietà descrive se gli elementi possono superare una dimensione di base, non come dovrebbe comportarsi in base a una base.
flex-shrink
Sì, questa proprietà descrive come gestire le dimensioni se la larghezza scende al di sotto della base.
flex-basis
Questo fornisce il punto di partenza per il dimensionamento, ma non come gestire gli scenari di dimensionamento in cui la larghezza scende al di sotto della base, come in uno scenario schiacciato.

Panoramica dell'allineamento Flexbox

Flexbox portava con sé un insieme di proprietà per allineare gli elementi e distribuire lo spazio tra gli stessi. Queste proprietà sono state così utili da essere state spostate nelle rispettive specifiche, che puoi trovarle anche nel layout griglia. Qui puoi scoprire come funzionano quando utilizzi flexbox.

L'insieme di proprietà può essere inserito in due gruppi. Proprietà per la distribuzione dello spazio e proprietà per l'allineamento. Le proprietà che distribuiscono lo spazio sono:

  • justify-content: distribuzione dello spazio sull'asse principale.
  • align-content: distribuzione dello spazio sull'asse trasversale.
  • place-content: un modo rapido per impostare entrambe le proprietà precedenti.

Proprietà utilizzate per l'allineamento in flexbox:

  • align-self: allinea 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-. Sulla croce, iniziano con align-.

Distribuzione dello spazio sull'asse principale

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

Aggiungi la proprietà justify-content al contenitore flessibile e assegnale un valore pari a flex-end: gli elementi verranno mostrati alla fine del contenitore e lo spazio libero verrà 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 dei valori possibili.

Con flex-direction: column

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

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

Distribuzione dello spazio tra le linee flessibili

Con un contenitore 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, il valore iniziale di align-content è stretch. Aggiungi la proprietà align-content al contenitore flessibile per modificare questo comportamento predefinito.

.container {
  align-content: center;
}

Prova questa procedura nella demo. L'esempio presenta righe aggregate di elementi flessibili e il container ha un block-size per liberare spazio.

L'abbreviazione di place-content

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

.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 */
}

Allineare gli elementi sull'asse trasversale

Sulla linea trasversale puoi anche allineare gli elementi all'interno della linea flessibile utilizzando align-items e align-self. Lo spazio disponibile per questo allineamento dipende dall'altezza del contenitore 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 all'altezza dell'elemento più alto per impostazione predefinita. Per modificare questa impostazione, aggiungi la proprietà align-self a tutti gli elementi flessibili.

.container {
  display: flex;
}

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

Utilizza uno qualsiasi 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 valore flex-start. Prova a modificare il valore di quella proprietà per vedere come si sposta all'interno del relativo 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;
}

Nella prossima demo prova a modificare il valore di align-items per allineare tutti gli elementi sull'asse incrociato come gruppo.

Perché non c'è "giustificazione" in flexbox?

Gli elementi flessibili fungono da gruppo sull'asse principale. Quindi non esiste il concetto di suddivisione di un singolo elemento da quel gruppo.

Nel layout a griglia, le proprietà justify-self e justify-items operano sugli assi in linea per eseguire l'allineamento degli 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.

È importante sapere che Flexbox funziona molto bene con i margini automatici. Se hai la necessità di suddividere un elemento da un gruppo o il gruppo in due gruppi, puoi applicare un margine. Nell'esempio riportato di seguito, 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 l'elemento viene spostato a destra e i gruppi vengono suddivisi.

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 incrociato.

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

Verifica la tua comprensione

Verifica le tue conoscenze su Flexbox

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

Per allineare verticalmente con flexbox, utilizza

allinea le parole chiave
Bene
giustifica le parole chiave
Dispiaciuto
.container {
  display: flex;
  direction: ltr;
}

Per allineare orizzontalmente con flexbox, utilizza

allinea le parole chiave
Dispiaciuto
giustifica le parole chiave
Bene
.container {
  display: flex;
  direction: ltr;
}

Per impostazione predefinita, gli elementi flessibili sono allineati a stretch. Se vuoi che le dimensioni dei contenuti vengano utilizzate per gli elementi secondari, quale dei seguenti stili useresti?

justify-content: flex-start
La proprietà giustifica è per l'allineamento orizzontale, non verticale.
align-content: start
content allinea le linee flessibili, non l'allineamento dell'elemento secondario.
height: auto
Questa operazione non avrà alcun effetto.
align-items: flex-start
Sì, vogliamo allinearli verticalmente al livello "in alto" o all'inizio; in questo modo il valore di elasticità predefinito viene rimosso e viene utilizzata invece l'altezza dei contenuti.

Risorse