Errori e fix
Centrare un elemento: i quattro modi corretti e quando usarli
Grid, flex, margin auto e posizionamento assoluto risolvono casi diversi. La scelta dipende da cosa deve centrare: un contenuto, un blocco o un overlay.
In sintesi
- Per un contenuto dentro un contenitore: `display: grid; place-items: center` è la forma più corta.
- Per un blocco con larghezza fissa: `margin-inline: auto` non richiede un contenitore flessibile.
- Per un overlay: `position: absolute; inset: 0; margin: auto` evita il transform e i suoi arrotondamenti.
Risposta breve: per centrare un contenuto dentro un contenitore usa display: grid; place-items: center. Per un blocco con larghezza nota, margin-inline: auto. Per un overlay, inset: 0; margin: auto. Il transform serve meno di quanto sembri.
Centrare è distribuire lo spazio libero
Un elemento si centra solo se avanza spazio. Il browser misura la larghezza disponibile nel contenitore, sottrae quella del figlio e ottiene lo spazio libero; ogni metodo consuma quello spazio in modo diverso. Grid lo assegna alle tracce e poi allinea l'elemento dentro la traccia, flex lo distribuisce lungo l'asse principale, i margini automatici lo assorbono in parti uguali, il posizionamento assoluto lo divide fra i due lati dopo aver risolto inset.
Da qui la regola pratica: se il figlio occupa tutta la larghezza disponibile lo spazio libero è zero e nessun metodo lo sposta. Lo stesso vale in verticale quando il contenitore non ha un'altezza definita: una percentuale su un genitore senza altezza si risolve in auto, e il centraggio non ha nulla da distribuire.
Il passo diagnostico, prima di cambiare il CSS
Apri gli strumenti di sviluppo, seleziona il figlio e guarda il pannello Computed: se width coincide con quella del genitore, il problema è lo spazio libero, non il metodo. Poi confronta i due rettangoli dalla console.
const child = document.querySelector(".stage > *");
const box = child.getBoundingClientRect();
const parent = child.parentElement.getBoundingClientRect();
console.log({ freeX: parent.width - box.width, freeY: parent.height - box.height });
Se freeX è zero il figlio è largo quanto il contenitore: aggiungi un max-width o togli width: 100%. Se freeY è zero il contenitore è alto quanto il contenuto: serve un min-height. Solo dopo aver escluso questi due casi ha senso cambiare metodo.
I quattro metodi
1. Grid
.stage {
display: grid;
place-items: center;
min-height: 100dvh;
}
È la forma più corta e centra su entrambi gli assi senza conoscere le dimensioni del figlio. Funziona anche quando il contenuto è più alto del contenitore, a patto di gestire l'overflow.
2. Flex
.row {
display: flex;
align-items: center;
justify-content: center;
gap: 1rem;
}
Meglio del grid quando ci sono più elementi affiancati: il gap e l'allineamento restano espliciti. Su un solo figlio, grid è più breve.
3. Margin auto
.prose {
max-width: 68ch;
margin-inline: auto;
}
Non richiede un contenitore flessibile ed è la scelta giusta per il contenuto di un articolo. In verticale i margini automatici valgono zero, salvo che il genitore sia flex o grid.
4. Posizionamento assoluto
.overlay {
position: absolute;
inset: 0;
margin: auto;
width: min(90vw, 32rem);
height: fit-content;
}
Qui il vantaggio è non usare transform: translate(-50%, -50%), che a zoom non interi può produrre testo meno nitido. Con inset: 0 e margin: auto il centraggio lo calcola il browser.
Quale scegliere
| Caso | Metodo | Perché |
|---|---|---|
| un contenuto in una sezione | grid | una dichiarazione, entrambi gli assi |
| più elementi in riga | flex | gap e allineamento espliciti |
| testo di un articolo | margin auto | nessun contesto flessibile richiesto |
| overlay o dialog | absolute + inset | nessun transform, dimensioni libere |
Quando la correzione non funziona
Se il centraggio sembra funzionare ma il contenuto è tagliato, il contenitore ha un'altezza fissa e il figlio è più alto: serve min-height e overflow: auto. Se invece il figlio resta a sinistra con margin: auto, ha una larghezza pari al 100%: senza spazio libero non c'è nulla da distribuire.
Quando la correzione comune peggiora le cose
Aggiungere display: grid; place-items: center al wrapper è la correzione che circola di più, e su un figlio di testo fa danni: justify-items: center toglie lo stretch, quindi il paragrafo si restringe al contenuto e le righe si spezzano a metà. Il centraggio riesce, la leggibilità no.
Lo stesso vale per text-align: center messo su un contenitore che deve restare leggibile: centra il testo inline, non i blocchi, e su un elenco produce voci con la prima riga centrata e le successive a sinistra. Se il figlio deve conservare la sua larghezza, centra il blocco e lascia il testo a sinistra.
Un limite da mettere nel conto
Il centraggio con place-items: center non è raggiungibile quando il figlio supera il contenitore: l'overflow esce da entrambi i lati e la parte sinistra finisce fuori dall'area di scorrimento. Non è un difetto del browser, è la definizione di center. Con place-content: center e un min-height il contenuto resta centrato ma scorre; con justify-items: safe center il browser torna a start quando lo spazio non basta. Il supporto di safe è la parte da verificare, non da assumere.
Come prevenirlo
- Scegli un metodo per tipo di contenuto e usalo in tutto il progetto.
- Non centrare con
line-heightopadding: si rompe appena il testo va a capo. - Testa a 320px, 768px e 1440px: il centraggio che funziona su desktop spesso taglia su mobile.
Dove continuare
Nel catalogo: blocco hero, componenti e icone. Le guide: Flexbox e Grid per designer e UI kit, libreria o design system; il confronto: dark mode senza secondo design system.
Domande frequenti
`place-items: center` centra anche in verticale?
Sì, su una grid container. Con una sola riga e una sola colonna centra entrambi gli assi.
Perché `margin: auto` non centra in verticale?
Su un blocco in flusso normale i margini verticali automatici valgono zero. Funziona in verticale solo in un contesto flex o grid.
Il transform rende il testo sfocato?
Può produrre arrotondamenti subpixel a zoom non interi. Per un testo piccolo, preferisci grid o margin auto.
Come centro un elemento senza conoscere la sua altezza?
Con grid o flex non serve conoscerla. Con il posizionamento assoluto, `inset: 0` più `margin: auto` la calcola il browser.
E se il contenitore ha `overflow: auto`?
Il centraggio può tagliare il contenuto quando è più alto del contenitore. In quel caso usa `place-content: center` con `min-height` e padding.