Flex (flexbox) è semplicemente bellissimo. Tutti i web designer lo amano, perchè semplifica la creazione di pagine responsive. È un tipo di layout che permette ad un contenitore padre di modificare la lunghezza, la larghezza e l'ordinamento dei suoi elementi figli.
Gli elementi figli, quindi, a seconda delle impostazioni date, si disporranno in modo differente per riempire lo spazio del contenitore padre e tale disposizione sarà flessibile, cioè si allargherà e restringerà in base alla larghezza dello schermo.
Il contenitore padre può, a sua volta, contenere altri contenitori padri con altri elementi figli ecc.
È anche possibile accostare elementi fissi ad elementi flessibili impostando una larghezza stabilita.
Negli esempi utilizzo i div come elementi contenitori per garantire un risultato perfetto su tutti i browser.
NOTA: non dimenticare di applicare i vendor prefixes alle regole di stile per poter vedere correttamente i risultati su tutti i browser https://autoprefixer.github.io/
Modulo flexbox, le basi
Credo che il modo migliore per capirne bene il funzionamento sia utilizzare degli esempi.
Lo schema di base, per un padre con 3 figli è questo:
Abbiamo creato un contenitore padre con regola "display:flex" e 3 contenitori figli con un contenuto di uguale dimensione. Il risultato saranno tre colonne allineate a sinistra, con stessa larghezza e stessa altezza.
Esempio 1 (base):
A
B
C
Mettendo un contenuto maggiore in uno o più dei box figli, essi adatteranno le loro dimensioni (larghezza e altezza) al contenuto.
Nota: nel primo div figlio il testo si sposta sotto perchè separato da un tag <br>.
Esempio 2:
AA A
B
CCC
Ci sono regole per il contenitore padre e regole per i contenitori figli.
Gli elementi incolonnati invertono il loro ordine.
flex-wrap: wrap
A
B
C
D
E
F
G
H
I
L
M
N
O
P
Q
R
S
T
U
V
Z
Gli elementi possono essere separati e andare su una nuova linea se la larghezza del contenitore non è sufficiente a contenerli.
Il valore di default è nowrap. Nel caso dell'esempio, se lasciato tale valore, il risultato, senza modificare la larghezza massima del contenitore, sarebbe questo:
Il contenuto, cioè, esce dal contenitore.
flex-wrap: wrap-reverse
A
B
C
D
E
F
G
H
I
L
M
N
O
P
Q
R
S
T
U
V
Z
Le righe in cui sono stati disposti gli elementi si invertono.
justify-content: flex-start (default)
A
B
C
Gli elementi si allineano all'inizio (sinistra) del contenitore se non ne occupano tutto lo spazio.
justify-content: flex-end
A
B
C
Gli elementi si allineano alla fine (destra) del contenitore se non ne occupano tutto lo spazio.
justify-content: center
A
B
C
Gli elementi si allineano al centro del contenitore se non ne occupano tutto lo spazio.
justify-content: space-between
A
B
C
Gli elementi vengono disposti ad occupare tutto il contenitore, ponendo uno spazio tra uno e l'altro se non ne occupano tutto lo spazio.
justify-content: space-around
A
B
C
Gli elementi vengono disposti ad occupare tutto il contenitore, ponendo uno spazio intorno ad ognuno se non ne occupano tutto lo spazio.
La distanza dal bordo del contenitore è la metà di quella tra gli elementi.
justify-content: space-evenly
A
B
C
Gli elementi vengono disposti ad occupare tutto il contenitore, ponendo uno spazio intorno ad ognuno se non ne occupano tutto lo spazio.
A differenza di space-around la distanza tra gli elementi e la distanza dal bordo del contenitore è identica.
align-items: stretch (default)
A A
B
C C C
Gli elementi occupano tutta l'altezza impostata del contenitore.
align-items: flex-start
A A
B
C C C
Gli elementi regolano la propria altezza in base al contenuto e sono allineati al margine superiore del contenitore.
align-items: flex-end
A A
B
C C C
Gli elementi regolano la propria altezza in base al contenuto e sono allineati al margine inferiore del contenitore.
align-items: center
A A
B
C C C
Gli elementi regolano la propria altezza in base al contenuto e sono allineati al centro rispetto all'altezza del contenitore.
align-items: baseline
A
b
C
Gli elementi si dispongono secondo la linea di base del loro contenuto, quale che sia la loro altezza.
align-content: stretch (default)
A
B
C
D
E
F
G
H
I
L
M
N
O
P
Q
R
S
T
U
V
Z
Le righe del blocco di elementi si allungano per occupare tutta l'altezza impostata del contenitore.
NOTA: la proprietà "align-content" ha effetto solo su blocchi di elementi distribuiti su più righe. Negli esempi è stata, quindi, associata alla proprietà "flex-wrap: wrap".
align-content: flex-start
A
B
C
D
E
F
G
H
I
L
M
N
O
P
Q
R
S
T
U
V
Z
Il blocco di elementi si allinea al margine superiore del contenitore.
align-content: flex-end
A
B
C
D
E
F
G
H
I
L
M
N
O
P
Q
R
S
T
U
V
Z
Il blocco di elementi si allinea al margine inferiore del contenitore.
align-content: center
A
B
C
D
E
F
G
H
I
L
M
N
O
P
Q
R
S
T
U
V
Z
Il blocco di elementi si allinea verticalmente al centro del contenitore.
align-content: space-between
A
B
C
D
E
F
G
H
I
L
M
N
O
P
Q
R
S
T
U
V
Z
Se lo spazio in altezza del contenitore non viene riempito completamente dal blocco degli elementi, le righe vengono distanziate tra di loro per colmare tutto lo spazio fino al margine superiore e inferiore.
(Se le righe fossero più di due, le righe centrali sarebbero disposte ad uguale distanza tra di loro e dalle righe superiore e inferiore)
align-content: space-around
A
B
C
D
E
F
G
H
I
L
M
N
O
P
Q
R
S
T
U
V
Z
Se lo spazio in altezza del contenitore non viene riempito completamente dal blocco degli elementi, tra le righe viene posto il margine necessario a distribuirle in modo omogeneo per colmare l'altezza.
La distanza dai bordi è la metà della distanza tra le righe.
align-content: space-evenly
A
B
C
D
E
F
G
H
I
L
M
N
O
P
Q
R
S
T
U
V
Z
Se lo spazio in altezza del contenitore non viene riempito completamente dal blocco degli elementi, tra le righe viene posto il margine necessario a distribuirle in modo omogeneo per colmare l'altezza.
A differenza di space-around, la distanza tra le righe e la distanza delle righe dai bordi del contenitore è identica.
gap Property
A
B
C
A
B
C
A
B
C
A
B
C
La proprietà gap permette di impostare uno spazio definito tra gli elementi figli.
Nell'esempio è stato impostato uno spazio di 20px (gap: 20px;).
Lo spazio si dispone anche verticalmente tra gli elementi per la presenza della regola flex-wrap:wrap che sposta gli elementi su due righe in base alla larghezza del contenitore padre..
Possibile anche definire spazi differenti orizzontalmente e verticalmente (es. gap: 20px 30px;) .
display:flex e display:inline-flex, differenza
Due contenitori padri consecutivi a cui viene applicata la regola display:flex, si dispongono uno sopra all'altro.
Due contenitori padri consecutivi a cui viene applicata la regola display:inline-flex, si dispongono in linea.
Guarda l'esempio pratico
Regole applicabili agli elementi figli
NOTA: le regole per gli elementi figli, se applicate al contenitore padre, stabiliscono impostazioni comuni per tutti gli elementi figli. Tali regole possono, comunque, essere sovrascritte se applicate direttamente ad ogni singolo elemento figlio.
order: 1 / 2 / 3 / 4 ecc...(default 0)
flex-grow: 1 / 2 / 3 / 4 ecc...(default 0)
flex-shrink: 1 / 2 / 3 / 4 ecc...(default 1)
flex-basis: ..px (default auto)
flex: unisce flex-grow, flex-shrink e flex-basis - flex:none equivale a flex: 0 0 auto, che sta per: flex-grow: 0; flex-shrink: 1; flex-basis: auto - impostandolo su un unico valore numerico positivo, per ogni singolo elemento (flex: 1 / 2 / 3 ecc.), stabilisce la proporzione fra la larghezza degli elementi.
align-self: stretch / flex-start / flex-end / center / baseline (default auto) - con questa regola è possibile sovrascrivere, per un singolo elemento, quella impostata dal contenitore padre con align-items.
Esempi di regole applicate agli elementi figli
order:1/2/3 ecc...(default 0)
A
B
C
D
Gli elementi si dispongo secondo le regole di ordine impostate. In questo caso, ho impostato "order:1" all'elemento B e "order:2" all'elemento A.
Gli elementi senza ordine stabilito appaiono a sinistra di quelli con ordine impostato.
flex-grow: 1 / 2 / 3 / 4 ecc...(default 0)
A
B
C
D
Fattore di crescita proporzionale. Se la larghezza del contenitore padre aumenta, gli elementi si allargano mantenendo sempre la proporzione stabilita dal valore impostato.
Maggiore è il valore e maggiore è la crescita.
Nell'esempio ho impostato "flex-grow:1" per gli elementi A e C, ho impostato "flex-grow:2" per l'elemento B e "flex-grow:3" per l'elemento D.
Naturalmente, gli elementi non devono avere una larghezza massima stabilita, altrimenti, superato un certo grado espansione del contenitore, assumeranno tutti la stessa larghezza massima impostata.
flex-shrink: 1 / 2 / 3 / 4 ecc...(default 1)
A
B
C
D
Fattore di restringimento proporzionale. Se la larghezza totale degli elementi è maggiore della larghezza del contenitore padre, gli elementi si restringono mantenendo sempre la proporzione stabilita dal valore impostato.
Maggiore è il valore e maggiore è il restringimento.
Gli elementi devono avere una larghezza di base (o flex-basis) stabilita.
Nell'esempio, il contenitore padre ha larghezza massima impostata di 600px.
Gli elementi figli hanno una larghezza impostata di 400px e il flex-shrink impostato, da A a D, sui valori 2, 3, 4, 5.
Naturalmente, gli elementi non devono avere una larghezza minima stabilita.
flex-basis: ..px (default auto)
A
B
C
C
Specifica la larghezza iniziale, in pixel, di un elemento figlio. In base a questa larghezza, la flessibilità degli elementi sarà proporzionale.
Nell'esempio, gli elementi figli hanno flex-basis rispettivamente di 40px, 100px, 60px, 20px.
Naturalmente, gli elementi non devono avere una larghezza fissa, o massima, diversamente stabilita
Ottimizzazione per il mobile
Flexbox è flessibile, quindi adatta la larghezza degli elementi alla larghezza dello schermo.
Ovviamente, però, ad un certo punto gli elementi diventerebbero troppo stretti per una visualizzazione accettabile.
Rimediamo con le media query cambiando la regola display:flex in display:block fino ad una larghezza massima definita dello schermo.
Esempio:
Adesso non resta che giocarci un po'. Mettendo insieme e incrociando le regole del contenitore padre e degli elementi figli, provando e riprovando si possono scoprire tutte le possibilità date da flex, che sono davvero tante e la cosa bella è che flex è supportato da tutti i browser (vedi: https://caniuse.com/#feat=flexbox)
Moltissime le possibilità di applicazione: layout per siti web, gallerie di immagini, box vari, griglie. Sbizzarritevi.
Centrare un elemento
Con flex è possibile centrare perfettamente un elemento nel suo contenitore, orizzontalmente e verticalmente.
Esempio con testo:
Con flex potete creare delle tabelle, o delle griglie senza usare "table" e "grid".
I vantaggi sono la semplicità, la maggiore adattabilità ai vari schermi e la compatibilità con i browser.