--- title: Flexbox slug: Learn/CSS/CSS_layout/Flexbox translation_of: Learn/CSS/CSS_layout/Flexbox ---
Prerequisiti: | Le basi di HTML (leggi Introduzione a HTML) e nozioni sul funzionamento del CSS (leggi Introduzione a CSS.) |
---|---|
Obiettivo: | Apprendere l'utilizzo di Flexbox per impostare il layout delle pagine web. |
Per molto tempo, le uniche tecniche affidabili per creare layout CSS compatibili con tutti i browser utilizzavano elementi float e posizionamento. Funzionavano a sufficienza, ma erano per alcuni aspetti limitati e frustranti.
Per esempio con quelle tecniche era difficile o del tutto impossibile definire in maniera flessibile e vantaggiosa le seguenti impostazioni:
Nelle sezioni seguenti apprenderemo come flexbox faciliti notevolmente questi compiti. Iniziamo!
Questo articolo presenta una serie di esercizi per aiutare a comprendere il funzionamento di flexbox. Per cominciare copiamo in locale il file di partenza flexbox0.html presente in github. Carichiamolo con un browser moderno, ad esempio Firefox o Chrome e facciamo attenzione al codice nell'editor. É possibile in alternativa visionarlo attraverso la versione live.
Come vediamo la pagina è formata da un {{htmlelement("header")}} contenente il titolo principale, poi un elemento {{htmlelement("section")}} che contiene tre {{htmlelement("article")}}. Partiamo da questa situazione per creare un layout a tre colonne abbastanza comune.
Per cominciare occorre scegliere il gruppo di elementi che devono apparire come box flessibili; per farlo occorre impostare un valore particolare della proprietà {{cssxref("display")}} del loro elemento padre. In questo caso specifico desideriamo sistemare gli elementi {{htmlelement("article")}}, perciò agiamo sul loro contenitore {{htmlelement("section")}}:
section { display: flex; }
Questa impostazione trasforma <section> in un contenitore flex e gli elementi figli in componenti flex. Questo è l'aspetto che otteniamo:
Proprio così: con questa semplice regola abbiamo già ottenuto tutto ciò che volevamo! Il layout diventa multicolonna e le colonne che lo formano sono della medesima larghezza e lunghezza. Tutto ciò avviene grazie ai componenti flex, cioè i figli del contenitore impostato come flex, che, grazie a valori predefiniti, risolvono automaticamente problemi tipici come questo.
Ripassiamo cosa è avvenuto: l'elemento il cui valore di {{cssxref("display")}} è flex
si comporta come un elemento blocco all'interno della pagina, ma i suoi figli vengono disposti come componenti flex. Nella prossima sezione capiremo meglio che cosa significa. Notiamo che in alternativa possiamo usare il valore inline-flex
per display
cosicché gli elementi figlio diventano comunque componenti flex, ma il contenitore si comporta come un elemento in linea.
In qualità di componenti flex, gli elementi si dispongono lungo due assi:
display: flex
, che nel nostro esempio è {{htmlelement("section")}} è chiamato contenitore flex (flex container).Si tengano a mente queste definizioni durante le sezioni successive. In caso di confusione con i termini potete comunque tornare a rileggere questa sezione.
Flexbox offre una proprietà chiamata flex-direction {{cssxref("flex-direction")}} che indica quale direzione deve seguire l'asse principale, ovvero come vengono disposti i contenuti flexbox;il valore predefinito è row
, in modo che i contenuti si schierino in riga secondo il verso della lingua preimpostata dal browser, che per le quelle occidentali è da sinistra a destra.
Proviamo ad aggiungere la seguente dichiarazione alle regole di {{htmlelement("section")}}:
flex-direction: column;
Come vediamo i componenti tornano a schierarsi in colonna, come in un il flusso normale senza aggiungere CSS. Cancelliamo pure questa dichiarazione dall'esercizio, prima di continuare.
Nota: Potremmo anche invertire la disposizione dei componenti flex utilizzando i valori row-reverse
o column-reverse
. Sono da sperimentare!
Il problema che sorge nel layout quando la larghezza o l'altezza vengono esplicitate è che il gruppo dei contenuti flexbox potrebbe eccedere il limite del contenitore, guastando il layout. Diamo un'occhiata all'esempio flexbox-wrap0.html,di cui viene fornita la visione live. Per eseguire le procedure mostrate da questo punto in poi, salvate una copia del file in locale.
Come vediamo i contenuti figli eccedono effettivamente il limite del loro contenitore. Una possibile soluzione consiste nell'aggiungere la seguente dichiarazione alle regole di {{htmlelement("section")}}:
flex-wrap: wrap;
Proviamo anche ad aggiungere la seguente dichiarazione alle regole di {{htmlelement("article")}}:
flex: 200px;
Ricaricando possiamo notare il miglioramento che abbiamo ottenuto grazie queste modifiche.
Adesso possiamo notare che si sono formate un certo numero di righe, ovviamente tante quante ne servono per tutti i contenuti flexbox: quando un contenuto eccede i limiti, scala alla riga successiva. L'impostazione
flex: 200px
dichiarata per gli articoli significa che ognuno di essi occuperà almeno 200px; questa proprietà verrà discussa con maggior dettaglio più avanti nell'articolo. Notiamo anche che ciascuno degli ultimi contenuti che occupano l'ultima riga è molto più largo in modo da riempirla completamente.
Possiamo sperimentare ancora: innanzitutto assegnare alla proprietà {{cssxref("flex-direction")}} il valore row-reverse
, così da ottenere un layout con numerose righe come il precedente in cui però i contenuti si schierano a partire dall'angolo opposto della finestra del browser e fluiscono in maniera inversa.
Occorre notare a questo punto che esiste una forma contratta, {{cssxref("flex-flow")}, per le proprietà {{cssxref("flex-direction")}} e {{cssxref("flex-wrap")}} — }. É possibile per esempio sostituire
flex-direction: row; flex-wrap: wrap;
con
flex-flow: row wrap;
Ora torniamo al primo esempio per capire come determinare la proporzione che occupa ogni componente flex nello spazio rispetto ai componenti suoi pari. Riapriamo il file locale flexbox0.html, oppure, come punto di partenza, prendiamo il nuovo file flexbox1.html di cui viene fornita anche la versione live.
Cominciamo aggiungendo la seguente regola al termine del nostro CSS:
article { flex: 1; }
Si indica in questo modo un valore proporzionale, privo di unità di misura, che determina lo spazio che occupa ogni componente flex rispetto agli altri. In questo caso tutti gli elementi {{htmlelement("article")}} hanno valore 1, il che significa, al netto di spaziature interne (padding) ed esterne (margin), che lo spazio verrà equamente ripartito tra tutti i componenti. Questo è un valore relativo a tutti i componenti flex del medesimo gruppo, perciò, se invece di 1 viene scritto un altro valore, 400000 ad esempio, otteniamo lo stesso risultato.
Di seguito scriviamo questa regola:
article:nth-of-type(3) { flex: 2; }
Si noti, dopo aver ricaricando la pagina, che il terzo componente {{htmlelement("article")}} riempie il doppio dello spazio occupato da ciascuno degli altri due. Lo spazio totale è ora diviso in quattro, cioè una spaziatura per il primo elemento, una per il secondo e due per il terzo (1+1+2=4), quindi il primo e il secondo occupano un quarto (1/4) di spazio ciascuno mentre il terzo ne occupa due quarti (2/4) ovvero la metà.
Si può anche specificare una misura reale minima al di sotto del quale non è possibile andare. Correggiamo le regole degli articoli in questo modo:
article { flex: 1 200px; } article:nth-of-type(3) { flex: 2 200px; }
Con queste regole affermiamo fondamentalmente quanto segue: "Ogni componente flex occupa almeno 200px nello spazio a disposizione, mentre lo spazio che rimane viene occupato rispettando le unità proporzionali." Ricaricando la pagina possiamo notare la differenza nella ripartizione delle spaziature.
La potenza di flexbox risiede nella sua flessibilità ovvero nella responsività con cui gestisce il layout: se ridimensioniamo la finestra del browser oppure inseriamo un nuovo elemento {{htmlelement("article")}} il layout continuerà a funzionare bene.
La proprietà {{cssxref("flex")}} rappresenta la forma contratta delle seguenti tre proprietà::
È consigliabile non utilizzare le forme estese della proprietà flex, a meno che non si possa fare altrimenti, come per esempio sostituire un valore stabilito in precedenza, perché costringono a scrivere una maggior quantità di codice che può risultare in qualche modo confusionario.
Con flexbox è possibile allineare i componenti flex lungo l'asse principale (main axis) o lungo l'asse traverso (cross axis). Facciamo alcune prove con la nuova pagina di esempio, flex-align0.html di cui è presente anche la versione live , per mostrare come creare una bottoniera, o barra degli strumenti, semplice e flessibile.
Apriamo il codice in locale.
Aggiungiamo al termine del file CSS la regola seguente:
div { display: flex; align-items: center; justify-content: space-around; }
Dopo aver ricaricato la pagina, i bottoni vengono ben centrati, sia orizzontalmente che verticalmente. Abbiamo ottenuto questo risultato operando con due nuove proprietà:
Attraverso {{cssxref("align-items")}} controlliamo l'allineamento rispetto all'asse traverso (cross axis).
stretch
, che allunga o comprime tutti i componenti flex affinché riempiano lo spazio del loro contenitore lungo l’asse traverso (cross axis). In un contenitore che non ha una misura fissa lungo l’asse traverso, tutti quanti suoi componenti assumono la lunghezza del maggiore fra di loro, perciò nel primo esempio dell'articolo tutti i componenti risultano della stessa altezza senza doverlo specificare.center
, per cui ogni componente si dimensiona in funzione del contenuto che possiede, in base a questa dimensione viene quindi centrato lungo l’asse traverso. Questa è la ragione per cui, in questo esempio, i bottoni che sono centrati in verticale.flex-start
e flex-end
, che allineano i componenti rispettivamente all’inizio o al temine dell’asse traverso. Per i dettagli vai {{cssxref("align-items")}}.É possibile sostituire l'impostazione data da align-items {{cssxref("align-items")}} , utilizzando la proprietà {{cssxref("align-self")}} di ogni singolo componente figlio. Ad esempio se proviamo ad aggiungere la seguente regola:
button:first-child { align-self: flex-end; }
Dopo aver verificato l’effetto, possiamo cancellare questa regola per ritornare alla situazione precedente.
Attraverso {{cssxref("justify-content")}} controlliamo il tipo di schieramento dei componenti flex lungo l'asse principale (main axis).
flex-start
, per cui il gruppo dei componenti si posiziona all'inizio dell'asse principale.flex-end
, il gruppo si posiziona al termine.center
o altrimenti justify-content
, l'allineamento parte dal centro dell'asse principale.space-around
, che è il valore utilizzato nell'esempio, i componenti si distribuiscono equamente lungo l'asse principale; inoltre viene creato un margine all'inizio e al termine dell'asse.space-between
impostiamo una situazione molto simile a space-around
, eccettuati i margini alle estremità che non vengono creati.É consigliabile sperimentare le proprietà con valori suddetti prima di continuare a leggere l'articolo.
Con flexbox è possibile cambiare l'ordine dei componenti senza intervenire manualmente nel sorgente HTML. Questa opportunità non esisteva con le metodologie di layout precedenti.
Proviamo ad aggiungere al CSS una nuova semplice regola:
button:first-child { order: 1; }
Una volta ricaricato notiamo che il bottone con label "Sorriso" si è spostato al termine dell'asse principale. Vediamo in dettaglio cosa è successo:
Se impostiamo un valore negativo di order, il componente compare prima di quelli con valore 0. Proviamo ora ad applicare la regola impostando per esempio l'ordine del bottone "Imbarazzo":
button:last-child { order: -1; }
Con flexbox possiamo creare layout piuttosto complessi; è del tutto lecito impostare un componente flex in modo che contenga a sua volta componenti annidati flex che vengono visualizzati come flex box. Diamo un'occhiata a complex-flexbox.html (see it live also).
La struttura HTML è abbastanza semplice, l'elemento {{htmlelement("section")}} contiene gli elementi figli {{htmlelement("article")}}. , il terzo di questi contiene tre {{htmlelement("div")}} :
section - article article article - div - button div button div button button button
Ora guardiamo il codice che ha creato il layout.
Innanzitutto, impostiamo i figli di {{htmlelement("section")}} affinché diventino flex box.
section { display: flex; }
Quindi valorizziamo alcune proprietà flex all'interno degli stessi {{htmlelement("article")}}. Si noti in particolare la seconda regola, in cui si impone che il terzo elemento {{htmlelement("article")}} abbia a sua volta componenti innestati flex, i quali però devono essere incolonnati.
article { flex: 1 200px; } article:nth-of-type(3) { flex: 3 200px; display: flex; flex-flow: column; }
Quindi, impostiamo per il primo <div> la proprietà flex a 1 100px; in modo che abbia un'altezza reale di almeno 100px; la proprietà successiva stabilisce che anche gli elementi figli, cioè i (the {{htmlelement("button")}}, divengano componenti flex; tali elementi si dispongono in riga e allineati a partire dal centro dello spazio disponibile mantenendo i margini alle estremità, proprio come l'esempio del bottone visto in precedenza.
article:nth-of-type(3) div:first-child { flex:1 100px; display: flex; flex-flow: row wrap; align-items: center; justify-content: space-around; }
Infine viene definita una regola per la dimensione dei bottoni., ma la parte più interessante è la proprietà flex che ha valore 1 auto; questa impostazione genera un comportamento peculiare che notiamo quando restringiamo la finestra del browser: i bottoni cercano di occupare il massimo dello spazio disponibile, si schierano uno accanto all'altro finché c'è spazio disponibile, e poi scalano alla riga seguente.
button { flex: 1 auto; margin: 5px; font-size: 18px; line-height: 1.5; }
Gran parte delle ultime versioni dei browser supportano flexbox, cioè Firefox, Chrome, Opera, Microsoft Edge, IE 11, le versioni recenti di Android/iOS ecc. Occorre tuttavia considerare anche la presenza delle versioni antiquate dei browser che non supportano flexbox oppure lo fanno solo parzialmente.
Il problema non incide granché quando ne studiamo e ne proviamo le funzionalità, tuttavia quando si cerca di utilizzare flexbox per creare un sito web reale dobbiamo controllare e assicurarci che l'esperienza utente sia comunque accettabile in quanti più browser possibile.
Applicare flexbox è un po' più complicato di altre funzionalità CSS. Se per esempio il browser non supporta l'ombreggiatura (drop shadow) è facile che l'usabilità del sito rimanga comunque valida, se invece manca il supporto a flexbox è probabile che il layout della pagina si disintegri rendendola inutilizzabile.
Le strategie per ovviare ai problemi di compatibilità tra browser vengono affrontate nel modulo Cross browser testing.
Questo articolo è denso di informazioni, ma riesci a ricordare quelle più importanti?
Prima di continuare possiamo verificare la nostra comprensione alla pagina Test your skills: Flexbox.
In conclusione dell'articolo sulle basi di flexbox speriamo di aver suscitato interesse e un buon punto di partenza nel nostro percorso di apprendimento. Nel prossimo articolo ci occupiamo di un altro importante aspetto del layout CSS: le Griglie CSS.