Flexbox è arrivato in tutti i principali browser intorno al 2015 e ha immediatamente risolto il problema che gli sviluppatori aggiravano con soluzioni di fortuna da un decennio: il centraggio verticale. Ma la maggior parte delle persone l'ha imparato al contrario — hanno memorizzato justify-content: center da un foglio di riferimento senza capire il perché funziona. Quando il layout non si comporta come previsto, quella lacuna nella comprensione trasforma un compito da cinque minuti in un'ora di tentativi ed errori. Questa guida costruisce prima il modello mentale, poi copre ogni proprietà che conta davvero nei progetti reali.
Il Modello Mentale: Un Asse alla Volta
Il concetto fondamentale di Flexbox è che dispone gli elementi lungo un singolo asse. C'è un asse principale — la direzione in cui scorrono gli elementi — e un asse trasversale, che corre perpendicolarmente. L'intuizione critica che quasi ogni principiante manca: flex-direction determina quale asse è quale. Tutto il resto deriva da questo.
/* Default: main axis runs LEFT → RIGHT, cross axis runs TOP → BOTTOM */
.container {
display: flex;
flex-direction: row; /* default */
}
/* Rotated: main axis now runs TOP → BOTTOM, cross axis runs LEFT → RIGHT */
.container {
display: flex;
flex-direction: column;
}
/*
justify-content → controls alignment on the MAIN axis
align-items → controls alignment on the CROSS axis
This is why centering something in both axes looks like this:
*/
.center-both {
display: flex;
justify-content: center; /* horizontally centred (main axis = row) */
align-items: center; /* vertically centred (cross axis) */
}flex-direction: column, justify-content non controlla più l'allineamento orizzontale — controlla l'allineamento verticale, perché l'asse principale è ruotato. align-items ora controlla l'orizzontale. Tieni a mente questa rotazione ogni volta che qualcosa non si allinea dove ti aspetti.Proprietà del Contenitore
Queste proprietà si applicano al contenitore flex — l'elemento padre con display: flex. Controllano come tutti gli elementi figli vengono distribuiti e allineati.
/* display: flex makes the element a block-level flex container.
display: inline-flex makes it inline (sits in text flow). */
.nav {
display: flex;
}
/* flex-direction — which way does the main axis run? */
.nav {
flex-direction: row; /* left to right (default) */
flex-direction: row-reverse; /* right to left */
flex-direction: column; /* top to bottom */
flex-direction: column-reverse; /* bottom to top */
}
/* flex-wrap — what happens when items overflow the container? */
.card-grid {
flex-wrap: nowrap; /* all items forced onto one line (default) */
flex-wrap: wrap; /* items wrap onto additional lines */
flex-wrap: wrap-reverse; /* items wrap in reverse order */
}
/* gap — space between items. Modern approach; avoids margin hacks. */
.card-grid {
gap: 1.5rem; /* same in both directions */
gap: 1rem 2rem; /* row-gap column-gap */
}La proprietà gap merita una menzione speciale. Prima che esistesse, il pattern comune era aggiungere margini agli elementi flex e poi annullare i bordi esterni con margini negativi. gap sostituisce tutto questo in modo pulito — usalo ovunque al posto di quel metodo.
/* justify-content — alignment on the MAIN axis */
.nav {
justify-content: flex-start; /* packed to start (default) */
justify-content: flex-end; /* packed to end */
justify-content: center; /* packed to centre */
justify-content: space-between; /* first/last at edges, equal gaps between */
justify-content: space-around; /* equal space around each item */
justify-content: space-evenly; /* equal space between every gap */
}
/* align-items — alignment on the CROSS axis (single line) */
.nav {
align-items: stretch; /* items fill cross-axis height (default) */
align-items: flex-start;/* items align to start of cross axis */
align-items: flex-end; /* items align to end of cross axis */
align-items: center; /* items centred on cross axis */
align-items: baseline; /* items aligned by their text baseline */
}
/* align-content — cross-axis alignment when there are MULTIPLE lines
(only takes effect with flex-wrap: wrap and enough items to wrap) */
.card-grid {
flex-wrap: wrap;
align-content: flex-start; /* rows packed to top */
align-content: center; /* rows centred vertically */
align-content: space-between; /* rows spread out with space between */
}Ecco una vera barra di navigazione che combina tutto questo. Il logo si trova a sinistra e i link di navigazione vengono spinti a destra usando margin-left: auto — un classico trucco di Flexbox. L'approccio con justify-content: space-between funziona anche, ma la tecnica del margine automatico è più flessibile quando si hanno più di due gruppi.
/* Nav: logo left, links right */
.site-nav {
display: flex;
align-items: center;
gap: 1rem;
padding: 0 2rem;
height: 64px;
background: #1a1a2e;
}
.site-nav .logo {
font-size: 1.25rem;
font-weight: 700;
color: #fff;
text-decoration: none;
}
.site-nav .nav-links {
display: flex;
align-items: center;
gap: 1.5rem;
margin-left: auto; /* pushes everything after it to the right */
list-style: none;
margin-top: 0;
margin-bottom: 0;
padding: 0;
}
.site-nav .nav-links a {
color: #ccc;
text-decoration: none;
font-size: 0.9rem;
}
.site-nav .nav-links a:hover {
color: #fff;
}Proprietà degli Elementi
Queste proprietà si applicano agli elementi flex — i figli diretti del contenitore flex. Controllano come i singoli elementi crescono, si restringono e si dimensionano.
flex-grow— quanto spazio libero disponibile questo elemento occupa. Default0(non crescere). Impostato a1su un elemento, prende tutto lo spazio rimanente.flex-shrink— quanto questo elemento si restringe rispetto agli altri quando lo spazio non è sufficiente. Default1. Impostato a0per impedire a un elemento di restringersi.flex-basis— la dimensione iniziale dell'elemento prima di qualsiasi crescita o restringimento. Può essere una lunghezza (250px,30%) oauto(usa la dimensione del contenuto dell'elemento).align-self— sovrascrivealign-itemsper un elemento specifico. Accetta gli stessi valori:auto,flex-start,flex-end,center,baseline,stretch.order— cambia l'ordine visivo senza toccare l'HTML. Default0. Valori più bassi appaiono prima. Usare con parsimonia — rompe l'ordine di tabulazione e causa problemi di accessibilità per utenti da tastiera e screen reader.
/* Classic sidebar + main content layout */
.app-layout {
display: flex;
min-height: 100vh;
}
.sidebar {
flex: 0 0 280px; /* don't grow, don't shrink, always 280px wide */
background: #f5f5f5;
padding: 2rem 1.5rem;
}
.main-content {
flex: 1; /* grow to fill all remaining space */
padding: 2rem;
min-width: 0; /* critical: prevents content overflow in flex children */
}
/* Responsive: stack vertically on mobile */
@media (max-width: 768px) {
.app-layout {
flex-direction: column;
}
.sidebar {
flex: none; /* reset — don't use flex-basis on column layout */
}
}min-width: 0: Per impostazione predefinita, gli elementi flex non possono restringersi al di sotto della loro dimensione minima del contenuto. Se hai una parola lunga o una tabella larga all'interno di un elemento flex, traboccherà invece di andare a capo. Aggiungere min-width: 0 all'elemento flex risolve questo problema. Si presenta costantemente nell'area del contenuto principale nei layout con barra laterale.La Proprietà Abbreviata flex Spiegata
La proprietà abbreviata flex racchiude flex-grow, flex-shrink e flex-basis in un'unica dichiarazione. La specifica W3C definisce una serie di valori chiave che coprono i casi comuni, e vengono spesso confusi tra loro.
/* flex: 1
Expands to: flex-grow: 1; flex-shrink: 1; flex-basis: 0%
Meaning: grow and shrink freely; start from zero (ignore content size).
All items with flex: 1 share space equally, regardless of content.
Most common choice for "fill available space". */
.tab { flex: 1; }
/* flex: auto
Expands to: flex-grow: 1; flex-shrink: 1; flex-basis: auto
Meaning: grow and shrink freely; start from the item's content size.
Items with more content get more space — proportional, not equal. */
.column { flex: auto; }
/* flex: none
Expands to: flex-grow: 0; flex-shrink: 0; flex-basis: auto
Meaning: completely rigid — don't grow, don't shrink, stay at content size.
Use for items that should never flex (icons, avatars, fixed labels). */
.avatar { flex: none; }
/* flex: 0 0 200px
Explicit: don't grow, don't shrink, always exactly 200px.
Same as writing out all three values. More readable for fixed-size items. */
.sidebar { flex: 0 0 200px; }
/* Practical difference: flex: 1 vs flex: auto in a tab bar
With flex: 1 → all tabs are equal width regardless of label length
With flex: auto → "Settings" tab is wider than "Home" tab */
.tabs { display: flex; }
.tab-equal { flex: 1; } /* equal width tabs */
.tab-auto { flex: auto; } /* content-sized tabs */Layout Reali Comuni
Ecco quattro pattern a cui ricorrerai regolarmente — costruiti con nient'altro che Flexbox.
/* 1. Sticky footer
The footer always sits at the bottom, even on short pages.
body (or .app-shell) becomes a column flex container. */
body {
display: flex;
flex-direction: column;
min-height: 100vh;
margin: 0;
}
main {
flex: 1; /* expands to push footer down */
}
footer {
/* stays at the bottom */
}/* 2. Centred modal / hero content
Both axes centred — the Flexbox vertical-centring party trick. */
.hero {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
padding: 2rem;
background: linear-gradient(135deg, #667eea, #764ba2);
}
.hero-content {
max-width: 640px;
text-align: center;
color: #fff;
}/* 3. Nav bar: logo left, links right */
.site-nav {
display: flex;
align-items: center;
padding: 0 2rem;
height: 64px;
}
.site-nav .nav-links {
margin-left: auto; /* auto margin consumes all free space to its left */
display: flex;
gap: 1.5rem;
list-style: none;
padding: 0;
margin-top: 0;
margin-bottom: 0;
}/* 4. Card row that wraps on mobile */
.card-grid {
display: flex;
flex-wrap: wrap;
gap: 1.5rem;
}
.card {
flex: 1 1 280px; /* grow and shrink, but never below 280px wide */
background: #fff;
border-radius: 8px;
padding: 1.5rem;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}
/* On wide screens: 3-4 cards per row.
On narrow screens: cards wrap into their own rows automatically.
No media query needed for the wrap itself — flex-wrap handles it. */Flexbox vs Grid — Quando Usare Quale
Questa domanda emerge continuamente, e la risposta è più semplice di quanto la maggior parte degli articoli faccia sembrare: Flexbox è per layout unidimensionali. CSS Grid è per layout bidimensionali. Se stai disponendo elementi in una singola riga o una singola colonna — una barra di navigazione, un gruppo di pulsanti, una riga di schede — Flexbox è lo strumento giusto. Se hai bisogno di controllare righe e colonne simultaneamente — un layout a pagina intera, un mosaico fotografico, una griglia di moduli — usa Grid.
In pratica, userai entrambi nello stesso progetto. Grid gestisce la struttura a livello di pagina (intestazione, barra laterale, principale, piè di pagina). Flexbox gestisce i componenti all'interno di quelle regioni (la barra di navigazione, il contenuto della scheda, il gruppo di pulsanti all'interno di un modale). Si completano a vicenda invece di competere.
flex-wrap: wrap può farlo, ma gli elementi nella stessa riga visiva non hanno alcuna relazione tra loro — le loro altezze sono indipendenti. Il dimensionamento implicito delle righe di Grid gestisce questo automaticamente. Se hai bisogno che le schede in una riga avvolta abbiano tutte la stessa altezza E i loro elementi interni si allineino tra le schede, Grid è più pulito.Conclusione
Il modello mentale di Flexbox è: scegli una direzione, capisci quali proprietà controllano quale asse, poi scegli se gli elementi devono crescere, restringersi o rimanere fissi. Una volta che questo scatta, il foglio di riferimento diventa una consultazione — non una stampella. La guida MDN su Flexbox è il miglior riferimento per i casi limite, e la guida completa di CSS-Tricks rimane il foglio di riferimento visivo più utile in circolazione. Per l'uso in produzione, il supporto browser è essenzialmente universale — nessun prefisso necessario. La specifica W3C vale la pena di essere scorsa se si incontra un caso limite genuinamente confuso — l'algoritmo è documentato con precisione e risponde alla maggior parte delle domande "perché si comporta così".