Flexbox e CSS Grid sono i due sistemi di layout moderni del CSS e sono supportati da tutti i browser attuali. Non sono concorrenti: risolvono problemi diversi e nella stessa pagina convivono quasi sempre. Capire la differenza di fondo ti evita di forzare uno dei due a fare un lavoro per cui non è nato.
La differenza essenziale: una dimensione o due
Flexbox dispone gli elementi lungo un solo asse alla volta, orizzontale o verticale. Gli elementi possono andare a capo, ma ogni riga viene calcolata in modo indipendente dalle altre: non c'è allineamento tra colonne di righe diverse.
Grid lavora su due dimensioni contemporaneamente. Definisci righe e colonne e poi collochi gli elementi nelle celle. Gli elementi della seconda riga si allineano esattamente alle colonne della prima.
Un altro modo utile di vederla: Flexbox parte dal contenuto (gli elementi si distribuiscono in base alle loro dimensioni), Grid parte dal contenitore (prima disegni la griglia, poi ci metti dentro le cose).
Quando Flexbox è la scelta naturale
Flexbox eccelle nei componenti lineari:
- barre di navigazione con logo a sinistra e link a destra;
- gruppi di pulsanti o di etichette (tag) che vanno a capo;
- centratura verticale e orizzontale di un elemento;
- una riga con un campo di testo che si allarga e un pulsante a larghezza fissa.
.toolbar {
display: flex;
align-items: center;
gap: 1rem;
}
.toolbar .search {
flex: 1; /* occupa lo spazio disponibile */
}
.toolbar .logo {
margin-right: auto; /* spinge il resto a destra */
}
La proprietà flex (scorciatoia di flex-grow, flex-shrink e flex-basis) è il cuore di Flexbox: decide come ogni elemento cresce o si restringe quando lo spazio cambia.
Quando Grid è la scelta naturale
Grid è lo strumento giusto quando ti interessa l'allineamento su righe e colonne:
- il layout generale della pagina (intestazione, barra laterale, contenuto, piè di pagina);
- gallerie di schede che devono avere colonne allineate;
- moduli con etichette e campi incolonnati;
- composizioni editoriali con elementi che occupano più celle.
Una galleria responsive senza media query:
.gallery {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
gap: 1.5rem;
}
Il browser crea tante colonne quante ne entrano, ognuna larga almeno 220 pixel, e distribuisce lo spazio residuo. Con Flexbox otterresti un risultato simile, ma l'ultima riga incompleta si allargherebbe in modo diverso dalle altre.
Le aree con nome
Una delle funzioni più leggibili di Grid è grid-template-areas, che ti permette di "disegnare" il layout:
.page {
display: grid;
grid-template-columns: 240px 1fr;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
}
.page > header { grid-area: header; }
.page > aside { grid-area: sidebar; }
.page > main { grid-area: main; }
.page > footer { grid-area: footer; }
@media (max-width: 700px) {
.page {
grid-template-columns: 1fr;
grid-template-areas: "header" "main" "sidebar" "footer";
}
}
Cambiare il layout su schermi piccoli diventa una questione di riscrivere poche righe.
Combinarli è la norma
Nella pratica quotidiana usi Grid per la struttura e Flexbox dentro i singoli componenti. La pagina è una griglia; la scheda dentro la griglia usa Flexbox in colonna per tenere il pulsante sempre in fondo:
.card {
display: flex;
flex-direction: column;
}
.card .actions {
margin-top: auto;
}
Così tutte le schede di una riga hanno il pulsante allineato in basso, anche se i testi hanno lunghezze diverse.
Subgrid
Quando vuoi che gli elementi interni di schede diverse si allineino tra loro (titoli, testi e pulsanti alla stessa altezza), Grid offre subgrid: l'elemento figlio eredita le tracce della griglia del genitore. È supportato dai browser moderni ed elimina molti trucchi con altezze fisse.
Proprietà in comune
Alcuni concetti valgono per entrambi e semplificano il passaggio dall'uno all'altro:
| Proprietà | Flexbox | Grid |
|---|---|---|
gap |
spazio tra gli elementi | spazio tra righe e colonne |
justify-content |
distribuzione sull'asse principale | distribuzione delle tracce |
align-items |
allineamento sull'asse trasversale | allineamento verticale nella cella |
order |
cambia l'ordine visivo | cambia l'ordine visivo |
Attenzione a order e al posizionamento libero di Grid: cambiano l'ordine visivo ma non quello del DOM. Chi naviga con la tastiera o con un lettore di schermo segue l'ordine del codice sorgente, quindi un riordino visivo troppo aggressivo crea confusione.
Un criterio pratico per decidere
Quando non sei sicuro, fatti tre domande:
- Mi serve allineamento sia orizzontale sia verticale tra elementi diversi? Allora Grid.
- Gli elementi devono adattarsi alle proprie dimensioni lungo una riga o una colonna? Allora Flexbox.
- Sto definendo la struttura di una pagina o di una sezione ampia? Di solito Grid; per i componenti interni, spesso Flexbox.
Nel mio lavoro di sviluppo web noto che molti problemi di layout "impossibili" nascono dall'aver scelto lo strumento sbagliato: una galleria fatta con Flexbox che non si allinea, o una barra di navigazione fatta con Grid che si rompe quando un link diventa più lungo.
In sintesi
- Flexbox dispone elementi lungo un asse; Grid lavora su righe e colonne insieme.
- Flexbox è ideale per barre, gruppi di pulsanti e componenti lineari.
- Grid è ideale per layout di pagina, gallerie e moduli incolonnati.
grid-template-areaserepeat(auto-fill, minmax())rendono il responsive molto semplice.- Usali insieme e non stravolgere l'ordine visivo rispetto al DOM.