Flexbox, ad un primo approccio, sembra quasi magico. Soprattutto per chi ha bazzicato CSS da prima della venuta di CSS3 e o prima dei moduli flexbox e grid.
Flexbox è quel modulo CSS che semplifica un sacco di cose, ma certe volte non si capisce perché si ottengano certi risultati.
Per evitare di impazzire dobbiamo quindi comprendere la base di flexbox. Per questo motivo in questo approfondimento non affronterò proprio tutto tutto sulle proprietà di flexbox, ma quelle cruciali per poterlo comprendere comunque a pieno.
Alla base di tutto c’è display: flex
. Se lo applichiamo ad un contenitore, come quello del markup che segue, tutti i suoi figli si posizioneranno uno a fianco all’altro.
1<nav id="main-navigation">
2 <ul class="menu">
3 <li class="menu-item">Home</li>
4 <li class="menu-item">About</li>
5 <li class="menu-item">Blog</li>
6 <li class="menu-item">Contatti</li>
7 <li class="menu-item">Richiedi preventivo</li>
8 </ul>
9</nav>
Di default i vari li
sono elementi di blocco, ciò significa che occupano tutto lo spazio a disposizione, nonostante la loro dimensione sia decisamente inferiore rispetto alla larghezza della finestra. Questo comportamento non ti dovrebbe ormai più stupire se hai seguito le altre lezioni del corso di CSS.
Dal momento che a .menu
applichiamo la proprietà display: flex
i discendenti diretti non saranno più block, ma saranno flex-item.
L’esito visuale dell’applicazione della proprietà è che tutti i vari list item saranno uno affianco all’altro.
Dal momento che gli elementi del listato sono flex-item si comporteranno come tali e se dovessi intervenire con una qualunque altro valore della proprietà display
, questa verrebbe ignorata.
Qual è però esattamente il compito di un flex-item? Il suo compito è quello di essere il più piccolo possibile mantenendo tutto su una riga.
La larghezza intrinseca dei flex-item è data dalla combinazione delle proprietà max-content
e min-content
.
La differenza sostanziale tra le due è che la prima fa sì che la dimensione massima di un elemento sia esattamente quella del suo contenuto, mentre la seconda è il contrario permettendo a, ad esempio, del testo di andare a capo, cosa che con max-content
non accade.
Il fatto che queste siano grandezze intrinseche significa che con flexbox non vengono definite dall’autore del CSS, ma sono gestite automaticamente.
Fintanto che c’è la possibilità di “comprimere” un flex-item, l’elemento in questione verrà rimpicciolito, fino a quando, a spazio esaurito, sarà costretto a fuoriuscire dal genitore.
Le due proprietà che controllano questo comportamento del flex-item sono flex-grow
e flex-shrink
. Le quali si applicano al flex-item e non al contenitore genitore.
Il valore di default di flex-shrink
è 1, ma possiamo disattivarlo mettendolo a 0. Cosa abbastanza inutile nel 90% dei casi in cui viene impiegato flexbox.
Ma cosa fa esattamente flex-shrink
? Questa proprietà è responsabile di quel rimpicciolimento osservato in precedenza (shrink in inglese significa restringere). Se disattivata quindi gli elementi non verranno ristretti e andranno in overflow prima rispetto al genitore.
La seconda proprietà è flex-grow
, il cui valore di default è 0. Qualora venisse modificato questo valore, il quale, come shrink è un rapporto, ciò significa che sono consentiti valori intermedi, come ad esempio 0.5 (decisamente più avanzati rispetto all’obiettivo che voglio ottenere con questa lezione), permette agli elementi flex di crescere in larghezza (grow per l’appunto). In altre parole, gli elementi saranno in grado di ripartirsi lo spazio a disposizione occupandolo del tutto.
Mandare a capo i flex item
Finora abbiamo visto proprietà applicate al flex-item
, ma giocare con shrink e grow non ha risolto il problema che ad un certo punto gli elementi vanno in overflow. Come risolviamo? Possiamo lavorare con il contenitore dei nostri flex-item. Possiamo usare la proprietà flex-wrap
, la quale accetta vari valori, ma quello che attualmente ci interessa è wrap
.
Questo valore comunica che quando non ci sarà più la possibilità di restringere i flex-item questi dovranno andare a capo. Un po’ come accade quando scriviamo del testo, finito lo spazio si va a capo. In alternativa qualora si volesse evitare questo andare a capo, si può impostare il valore di default che è nowrap
(senza trattino).
Come flexbox ridimensiona gli elementi
Sappiamo che flex-shrink
e flex-grow
giocano un ruolo cruciale su come i flex-item vengono renderizzati a video.
Flexbox inizialmente fa sì che l’elemento occupi il suo spazio ideale per poter essere mostrato su una sola riga (ciò che in pratica accade quando impostiamo flex-shrink a 0), una volta che ha stabilito questa larghezza, usa quei valori come punti di partenza per poterli ridimensionale e farli rientrare all’interno del contenitore.
Come far diventare tutti gli elementi della stessa larghezza
Può capitare, anzi è estremamente comune, che si voglia ridimensionare i vari flex-item affinché siano della stessa larghezza. Come si fa?
C’è una shorthand molto utile che si applica ai flex-item che è flex
. Questa proprietà è la scorciatoia per:
flex-grow: 1
flex-shrink: 1
flex-basis: 0
(il cui valore di default èauto
)
Ma cos’è esattamente flex-basis
? Puoi pensare a flex-basis
come ad una sorta di proprietà width
, per quanto differiscono sono estremamente simili e questo paragone spero ti permetta di comprendere che flex-basis
non è altro che la dimensione iniziale di un flex-item.
Modificare la direzione con flex-direction
Qualora la necessità fosse quella di modificare l’orientamento degli elementi, magari su dispositivi più grandi o più piccoli, flex-direction
è la proprietà ideale
Il suo valore di default è row
, ma possiamo cambiarlo con column
con una media query per ottenere la visualizzazione perfetta dei nostri elementi sia da desktop che da mobile.
Un punto cruciale di flex-direction
è che inverte la main axis e la cross axis (rispettivamente l’asse delle X e delle Y se pensiamo ad un piano cartesiano).
Questa modifica degli assi influenza una serie di proprietà che ancora non abbiamo visto, ma che andiamo ad esaminare immediatamente.
La proprietà della main axis: justify-content
justify-content
è una proprietà che funziona dal momento che c’è dello spazio sulla quale poter sistemare i vari flex-item.
I valori possibili di justify-content
sono:
center
: centra gli elementi sull’asse delle Xflex-start
(vale anchestart
): allinea gli elementi all’inizio del contenitore flexflex-end
(vale ancheend
): allinea gli elementi alla fine del contenitore flexspace-around
: distribuisce gli elementi su tutta l’asse delle X, ma con uno spazio dimezzato all’inizio e alla fine.space-evenly
: come space-around, ma lo spazio all’inizio e alla fine è identico a quelli tra gli elementispace-between
: non ci sono spazi all’inizio e alla fine e gli elementi hanno una spaziatura equa tra di loro.
Di default justify-content
lavora sull’asse delle X, ma se dovessimo modificare flex-direction
in column
, allora in quel caso l’asse di riferimento diventa la Y, la quale diventa la nuova main axis.
La proprietà della cross axis: align-items
Se justify-content
lavora sull’asse delle X (main axis), align-items
lavora su quella delle Y (cross axis).
I valori possibili sono:
stretch
(default): gli elementi occupano tutto lo spazio verticale possibile (così che elementi più corti siano pari con quelli più lunghi)center
: centra l’elemento più corto rispetto a quello più altoflex-start
: allinea gli elementi all’inizio del contenitore flex.flex-end
: allinea gli elementi alla fine del contenitore flex
Mentre align-items
è applicabile al contenitore flex, align-self
(accetta gli stessi valori) può essere applicata ai singoli flex-item.
Caricamento...
Diventiamo amici di penna? ✒️
Iscriviti alla newsletter per ricevere una mail ogni paio di settimane con le ultime novità, gli ultimi approfondimenti e gli ultimi corsi gratuiti puubblicati. Ogni tanto potrei scrivere qualcosa di commerciale, ma solo se mi autorizzi, altrimenti non ti disturberò oltre.
Se non ti piace la newsletter ti ricordo la community su Discord, dove puoi chiedere aiuto, fare domande e condividere le tue esperienze (ma soprattutto scambiare due meme con me). Ti aspetto!