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

CasoMetodoPerché
un contenuto in una sezionegriduna dichiarazione, entrambi gli assi
più elementi in rigaflexgap e allineamento espliciti
testo di un articolomargin autonessun contesto flessibile richiesto
overlay o dialogabsolute + insetnessun 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-height o padding: 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.