back to top

Centrare un elemento in verticale con i CSS

Centrare verticalmente un elemento all’interno di una pagina web (o di un contenitore specifico) è uno del problemi classici del web design. Se centrare un elemento orizzontalmente è molto semplice, infatti, la stessa cosa non può dirsi dell’operazione lungo l’asse verticale.

Diverse tecniche per centrare verticalmente: saper scegliere quella giusta

In realtà esistono diversi metodi per centrare un elemento in verticale utilizzando CSS ma la scelta di quale effettivamente utilizzare va valutata di volta in volta sulla base delle specifiche esigenze del caso concreto: non esiste in sostanza una tecnica universalmente valida ma tante diverse tecniche che offrono una soluzione a situazioni ben specifiche.

Ma prima di addentrarci nelle varie tecniche possibili facciamo una premessa facendo qualche considerazione sulla proprietà vertical-align che, diversamente da quello che si può pensare, non offre sempe il risultato previsto.

Centrare orizzontalmente e verticalmente: i limiti di vertical-align

Come abbiamo detto centrare un elemento in orizzontale è molto semplice:

  • se si tratta di un elemento inline sarà sufficiente applicare al suo contenitore la proprietà text-align con valore center;
  • se si tratta di un elemento block sarà sufficiente applicare al medesimo elemento la proprietà margin avendo cura di settare i margini laterali (left e right) come auto.

Un operazione così semplice, purtroppo, non è possibile per il centramento verticale. La proprietà vertical-align, diversamente da quello che si può pensare, infatti, non offre una risposta semplice come text-align: center in quanto, diversamente da quest’ultima, ha dei limiti piuttosto stringenti di utilizzo.

La proprietà vertical-align, infatti, oltre a produrre effetti solo su elementi inline, può essere applicata esclusivamente a:

  • degli elementi posizionati all’interno di blocchi di testo, come ad esempio <p> (in questo caso i suoi effetti sono condizionati dal valore di line-height dell’elemento genitore);
  • delle celle di tabelle oppure elementi stilizzati in modo analogo mediante la proprietà display con valore table-cell.

In tutte le altre situazioni, quindi, la proprietà vertical-align non risolve il problema.

Centrare verticalmente un elemento inline

Per prima cosa, quindi, vediamo come centrare un elemento inline utilizzando la proprietà vertical-align nei due modi visti sopra:

Utilizzare line-height e vertical-align

Vediamo come centrate verticalmente una linea di testo utilizzando vertical-align e line-height sull’elemento genitore.

Questo il markup HTML:

<div class="contenitore">
  ...contenuto da centrare verticalmente...
</div>

Questo il nostro stile:

div.contenitore {
  width: 500px;
  height: 300px;
  line-height: 300px;
  text-align: center;
  background: #CCC;
  vertical-align: middle;
}

Risultato:

Come potete vedere, nel nostro esempio, la stringa di testo risulterà centrata nel suo contenitore sia orizzontalmente che verticalmente.

N.B. Questa tecnica è perfetta per centrare una linea di testo, se il testo va su più linee, invece, è necessario a ricorrere ad un’altra tecnica.

Utilizzare table e table-cell

Grazie ai CSS è possibile simulare le tabelle grazie agli attributi table e table-cell della proprietà display.

Come detto, infatti, vertical-align svolge correttamente i suoi compiti all’interno di un contesto tabellare (vero o simulato che sia).

Per creare una struttura simil-tabellare abbiamo bisogno di due elementi annidiati a cui andremo ad assegnare, rispettivamente, il valore table e table-cell.

Questo il markup HTML:

<div class="genitore">
  <div class="figlio">
    ...contenuto da centrare verticalmente...<br>
    ...contenuto da centrare verticalmente...<br>
    ...contenuto da centrare verticalmente...<br>
    ...contenuto da centrare verticalmente...<br>
    ...contenuto da centrare verticalmente...
  </div>
</div>

Queste le istruzioni CSS:

div.genitore {
  display: table;  
  width: 500px;
  height: 300px;
  background: #CCC;
}
div.figlio {
  display: table-cell;
  vertical-align: middle;
  text-align: center;
}

Risultato:

Possiamo utilizzare questa tecnica anche per centrare un’immagine verticalmente rispetto al suo contenitore (nel nostro esempio è sufficiente inserire un tag <img> al posto del testo).

E’ bene precisare che questo metodo NON funziona su tutti i browser, in particolar modo non è supportato dalle versioni meno recenti di IE.

Centrare verticalmente un elemento block

Se per centrare verticalmente un elemento inline si ricorre alla proprietà vertical-align, questa non può esserci utile quando l’elemento da centrare è un blocco. In questo caso possiamo procedere in modi diversi a seconda delle specificità del caso.

Centrare verticalmente un elemento block con dimensioni conosciute

L’esigenza più semplice da affrontare consiste nel centrare verticalmente un elemento quando si conoscono le dimensioni del contenitore e del contenuto.

In questo caso, infatti, utilizzando posizionamenti relativi ed assoluti, il problema può essere facilmente risolto:

<div class="genitore">
  <div class="figlio">
  </div>
</div>

Queste le istruzioni CSS:

div.genitore {
  width: 500px;
  height: 300px;
  background: #CCC;
  position: relative;
}
div.figlio {
  width: 300px;
  height: 200px;
  background: #000;
  position: absolute;
  top: 50px;
  left: 100px;
}

Risultato:

Come potete vedere per centrare l’elemento figlio nel genitore è stato sufficiente assegnare un posizionamento relativo a quest’ultimo ed un posizionamento assoluto al primo al quale abbiamo assegnato, attraverso le proprietà di posizionamento top e left, delle coordinate ottenute mediante semplicissime operazioni matematiche:

top: (altezza_genitore - altezza_figlio) / 2
left: (larghezza_genitore - larghezza_figlio) / 2

Possiamo utilizzare questa tecnica anche per centrare un’immagine verticalmente rispetto al suo contenitore. Vediamo un esempio:

<div class="genitore">
  <img src="foto.jpg" />
</div>

CSS:

div.contenitore {
  width: 500px;
  height: 300px;
  background: #CCC;
  position: relative;
}
.contenitore img {
  display: block;
  width: 300px;
  height: 200px;
  position: absolute;
  top: 50px;
  left: 100px;
}

N.B. Si noti che l’immagine (elemento nativamente inline) è stato trasformato in elemento block.

Risultato:

Ovviamente tutto è risultato molto semplice perché si conoscevano esattamente le dimensioni degli elementi coinvolti. Quando queste dimensioni non sono conosciute (ad esempio perché la pagina si crea dinamicamente) le cose si fanno un poco più complicate…

Centrare verticalmente un elemento block con il posizionamento assoluto e margini negativi

Una variante della tecnica precedente consiste nell’utilizzo del posizionamento assoluto dell’elemento figlio che viene centrato utilizzando margini negativi.

<div class="genitore">
  <div class="figlio">
  </div>
</div>

Queste le istruzioni CSS:

div.genitore {
  width: 500px;
  height: 300px;
  background: #CCC;
  position: relative;
}
div.figlio {
  width: 300px;
  height: 200px;
  background: #000;
  position: absolute;
  top: 50%;
  left: 50%;
  margin: -100px 0 0 -150px;
}

Come potete vedere top e left sono impostati al 50% mentre i margini sono impostati in negativo e sono calcolati come la metà, rispettivamente, dell’altezza e della larghezza dell’elemento da centrare.

Centrare verticalmente un elemento utilizzando il padding

Un trucco molto semplice per creare un’allineamento verticale per un elemento di cui non si conosce l’altezza è utilizzare i padding dell’elemento genitore. Una simile soluzione, molto semplice, è praticabile unicamente quando l’elemento genitore non deve avere necessariamente un’altezza predefinita ma può dilatarsi nella pagina.

Il markup HTML è il medesimo del caso precedente. Questo il CSS:

div.genitore {
  width: 500px;
  background: #CCC;
  padding: 100px 0;
}
div.figlio {
  margin: 0 auto;
  background: #000;
}

Con questo semplice codice CSS l’elemento figlio risulterà centrato orizzontalmente grazie ai margini laterali impostati come auto e verticalmente grazie al fatto che il suo genitore ha un padding superiore ed inferiore dello stesso spessore.

Come detto questa tecnica è utilizzabile solo se il genitore non è vincolato ad un’altezza prestabilita: in questo caso, infatti, il genitore assume un’altezza variabile in dipendenza all’altezza del figlio alla quale si andrà a sommare lo spessore del padding superiore ed inferiore.

Centrare verticalmente un elemento utilizzando il posizionamento assoluto e lo streching

L’idea è quella di applicare un posizionamento relativo all’elemento genitore ed assoluto al figlio assegnando a quest’ultimo dei valori di posizionamento (top, bottom, left, right) pari a zero. In questo modo l’elemento viene idealmente "tirato" verso i quattro angoli dell’elemento genitore tuttavia, essendo più piccolo sarà possibile impostare i margini ad auto per ottenere la centratura.

Questo il markup HTML:

<div class="contenitore">
  <img src="foto.jpg" />
</div>

Di seguito lo stile applicato:

div.contenitore {
  width: 500px;
  height: 300px;
  background: #CCC;
  position: relative;
}
.contenitore img {
  display: block;
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  margin: auto;
}

Risultato:

Si noti che nel nostro esempio abbiamo centrato un’immagine applicando a quest’ultima il valore "block" per la proprietà display.

Centrare verticalmente usando le nuove proprietà di CSS3

E’ bene precisare fin da subito che i CSS3 non offrono ancora un supporto universale quindi il risultato non è cross-browser ed è esclusa ogni compatibilità coi browser più datati. Il consiglio, quindi, è di utilizzare con prudenza.

Centrare verticalmente utilizzando "display: box" sull’elemento genitore

Con CSS3 il W3C sta cercando di porre rimedio ad alcune lacune di CSS introducendo nuove features come ad esempio il nuovo attributo box per la proprietà display.

Grazie a "box" l’allineamento verticale diventa molto semplice: è sufficiente definire il genitore come "box" ed assegnare un paio di proprietà specifiche per ottenere l’effetto in questione:

<div class="genitore">
  <div class="figlio">
    ...contenuto da centrare verticalmente...<br>
    ...contenuto da centrare verticalmente...<br>
    ...contenuto da centrare verticalmente...<br>
    ...contenuto da centrare verticalmente...<br>
    ...contenuto da centrare verticalmente...
  </div>
</div>

Questo il CSS:

div.genitore {
  width: 500px;
  height: 300px;
  background: #CCC;

  /* W3C */
  display: box;
  box-pack: center;
  box-align: center;
  
  /* Internet Explorer 10 */
  display: -ms-flexbox;
  -ms-flex-pack: center;
  -ms-flex-align: center;
  
  /* Firefox */
  display: -moz-box;
  -moz-box-pack: center;
  -moz-box-align: center;
  
  /* Safari, Opera, and Chrome */
  display: -webkit-box;
  -webkit-box-pack: center;
  -webkit-box-align: center;
}
div.figlio {
  background: #000;
  color: #FFF;
}

Risultato:

Possiamo utilizzare questa tecnica anche per centrare un’immagine verticalmente rispetto al suo contenitore. Vediamo un esempio:

<div class="contenitore">
  <img src="foto.jpg" />
</div>

Applicando al contenitore lo stesso stile visto sopra per l’elemento "genitore".

Centrare verticalmente utilizzando transform

Un’altra tecnica per centrare verticalmente un elemento rispetto al suo genitore consiste nell’utilizzare la nuova proprietà transform dei CSS3.

Il markup HTML è sempre il medesimo, questo il codice CSS per questa tecnica:

div.genitore {
  width: 500px;
  height: 300px;
  background: #CCC;
  position: relative;
}
div.figlio {
  background: #000;
  color: #FFF;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);    
  -webkit-transform: translate(-50%, -50%);
  -moz-transform: translate(-50%, -50%);
  -ms-transform: translate(-50%, -50%);
}

Quello che abbiamo fatto è posizionare l’elemento figlio al 50% dell’altezza e della larghezza del suo contenitore (in pratica il suo margine sinistro superiore viene posizionato al centro del genitore) correggendo utilizzando la proprietà transform con attributo translate per spostare l’elemento in alto e a sinistra per il 50% delle sue dimensioni.

Risultato:

Possiamo utilizzare questa tecnica anche per centrare un’immagine verticalmente rispetto al suo contenitore. Vediamo un esempio:

<div class="contenitore">
  <img src="foto.jpg" />
</div>

Applicando questo stile CSS:

div.contenitore {
  width: 500px;
  height: 300px;
  background: #CCC;
  position: relative;
}
.contenitore img {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);    
  -webkit-transform: translate(-50%, -50%);
  -moz-transform: translate(-50%, -50%);
  -ms-transform: translate(-50%, -50%);
}

Risultato:

Conclusioni

Le tecniche passate in rassegna sono diverse e non tutte pienamente cross-browser, la scelta di quale utilizzare deve essere effettuata di volta in volta sulla base delle specifiche esigenze del progetto.

Altri contenuti interessanti

Pubblicità
Massimiliano Bossi
Massimiliano Bossi
Stregato dalla rete sin dai tempi delle BBS e dei modem a 2.400 baud, ho avuto la fortuna di poter trasformare la mia passione in un lavoro (nonostante una Laurea in Giurisprudenza). Adoro scrivere codice e mi occupo quotidianamente di comunicazione, design e nuovi media digitali. Orgogliosamente "nerd" sono il fondatore di MRW.it (per il quale ho scritto centinaia di articoli) e di una nota Web-Agency (dove seguo in prima persona progetti digitali per numerosi clienti sia in Italia che all'estero).

Leggi anche...

Stilizzare HR (linee orizzontali) in puro CSS

Il tag <hr> (Horizontal Rule) è un elemento HTML...

Immagini riflesse con CSS

Il Flipping è una tecnica utilizzata dai grafici per...

Applicare un bordo alle lettere di un testo con CSS

Con l'avvento di CCS3 il linguaggo di stilizzazione delle...

CSS: dimensioni relative alla viewport con vw, vh, vmin e vmax

Con l'avvento e la diffusione di CSS 3 e...

Rimuovere CSS inutilizzato

Soprattutto quando si gestiscono progetti Web based di grandi...

CSS: centrare orizzontalmente un elenco puntato

Il sistema migliore per scrivere un buon menu è...
Pubblicità