Articles

13 modi per centrare verticalmente

Posted on

Ai bei tempi, i limiti dei CSS erano tali che anche cose “semplici” come la centratura verticale rappresentavano una sfida, con alcuni di noi che si affidavano persino a soluzioni JavaScript. Era fragile, era molto limitato, e c’era sempre quell’eccezione che lo faceva fallire.

Che stessimo cercando di allineare un’icona o un’immagine accanto al testo, di creare uno di quei popolari banner “hero”, o una sovrapposizione modale, centrare le cose sull’asse verticale era sempre una lotta.

Ma i CSS hanno fatto molta strada da allora, fornendo molti metodi che hanno reso il centraggio verticale sempre più facile. Ecco un riassunto di alcuni di essi, insieme ai loro casi d’uso e limitazioni.

Posizionamento assoluto e margine automatico

Un elemento senza dimensioni intrinseche può essere “centrato” semplicemente usando valori uguali dalla parte superiore e inferiore. Quando l’elemento ha dimensioni intrinseche potremmo usare 0 per la parte superiore e inferiore, quindi applicare il margine automatico. Questo centrerà automaticamente l’elemento:

.container{ position:relative;}.element{ position:absolute; top: 0; bottom: 0; left: 0; right: 0; margin: auto; height: 20px; /*requires explicit height*/}

Vedi la penna
Centering 1: posizionamento assoluto di Facundo Corradini (@facundocorradini)
su CodePen.

La limitazione è, ovviamente, che l’altezza dell’elemento deve essere dichiarata esplicitamente, o occuperà l’intero contenitore.

Il classico top 50% translate -50%

Questo è uno dei primi, e ancora un go-to, per molti sviluppatori. Un trucco semplice, che si basa sul posizionamento assoluto dell’elemento interno al 50% dall’alto del suo genitore, poi lo traduce al 50% della sua altezza:

.container{ position: relative;}.element{ position: absolute; top: 50%; transform: translateY(-50%);}

Vedi la penna
Centering 2: top 50 translateY -50 di Facundo Corradini (@facundocorradini)
su CodePen.

Un approccio abbastanza solido, con l’unica grande limitazione dell’uso di translate che potrebbe intralciare altre trasformazioni, ad esempio quando si applicano transizioni/animazioni.

Tabelle. Sì, ho appena detto tabelle.

Un approccio molto semplice e uno dei primi (ai tempi, tutto era tabelle), è usare il comportamento delle celle della tabella e vertical-align per centrare un elemento sul contenitore.

Questo può essere fatto con tabelle vere e proprie (vergogna, vergogna, vergogna), o usando l’HTML semantico, passando la visualizzazione dell’elemento a table-cell:

.container{ display: table; height: 100%;}.element{ display: table-cell; text-align: center; vertical-align: middle;}

Vedi la penna
Centering 3: tables di Facundo Corradini (@facundocorradini)
su CodePen.

Questo funziona anche quando entrambi gli elementi sono di altezza sconosciuta. La limitazione maggiore è ovviamente se avete bisogno di avere un fratello non centrato, e potrebbe diventare complicato con i limiti dello sfondo.

Inoltre, tenete presente che questo fallisce totalmente sugli screen reader (anche se il vostro markup è basato su div, impostando il display CSS su table e table-cell lo farà interpretare agli screen reader come una vera e propria tabella). Lontano dal meglio quando si tratta di accessibilità.

Il metodo dell’elemento fantasma

Un altro vecchio metodo, che non ha preso piede per qualche motivo, è usare inline-block con un elemento fantasma (pseudo) che ha il 100% di altezza del genitore, quindi impostare la proprietà vertical-align su middle:

.container::before { content: ''; display: inline-block; height: 100%; vertical-align: middle; margin-left: -1ch;}.element{ display: inline-block; vertical-align: middle;}

Vedi il metodo Pen
Centering 4: ghost element di Facundo Corradini (@facundocorradini)
su CodePen.

In realtà funziona abbastanza bene, con il “difetto” più evidente che è che sposta il centro orizzontale appena un po’ a destra, a causa del comportamento sempre strano degli spazi bianchi tra gli elementi inline-block.

Questo può essere affrontato come faremmo con il problema degli inline-block in qualsiasi altro contesto, l’approccio più semplice è il margin-left -1ch che ho usato sopra (anche se questo non sarà accurato al 100% tranne che sui font monospace, poiché l’unità ch significa la larghezza del carattere “0”), oppure impostando la dimensione del font a 0 sul contenitore e poi reimpostandola a px o rem sull’elemento. Non ottimale, a dir poco.

Margine automatico su un flex-item

Finalmente entrando nel territorio dei CSS moderni, flexbox ha introdotto un comportamento piuttosto impressionante per i margini automatici. Ora, non solo centra orizzontalmente l’elemento come faceva nei layout a blocchi, ma lo centra anche sull’asse verticale:

.container{ display:flex;}.element{ margin:auto;}

Vedi la penna
Centering 5: margin:auto on a flex-item di Facundo Corradini (@facundocorradini)
su CodePen.

Questa tattica è una delle mie preferite per la sua semplicità, l’unica grande limitazione è che funziona solo con un singolo elemento.

Pseudo-elementi su un contenitore flessibile

Non è l’approccio più pratico del mondo, ma possiamo anche usare pseudo elementi flessibili e vuoti per spingere l’elemento al centro:

.container{ display:flex;}.element{ margin:auto;}

Vedi la penna
Centering 6: pseudos su una flexbox di Facundo Corradini (@facundocorradini)
su CodePen.

Questo può essere utile quando vogliamo mantenere una spaziatura flessibile su un contenitore flessibile orientato a colonne con più elementi.

7 & 8. Allineare sul flex-container o sul flex-item

Flexbox ha anche introdotto delle ottime proprietà di allineamento (che ora sono biforcate nel proprio modulo di allineamento del box). Questo ci permette di controllare come gli elementi sono posizionati e come lo spazio vuoto è distribuito in modi che avrebbero richiesto o numeri magici nei CSS per un numero specifico di elementi (o un JS abbastanza intelligente per quantità dinamiche).

A seconda della direzione del flex, potremmo usare justify-content o align-items per regolare come necessario.

Sul contenitore:

.container{ display: flex; justify-content: center; align-items: center;}

Vedi la penna
Centering 7: align on flex-container di Facundo Corradini (@facundocorradini)
su CodePen.

Su un particolare flex-item:

.container{ display: flex;}.element{ align-self: center; margin: 0 auto;}

Vedi la penna
Centering 8: align on flex-item di Facundo Corradini (@facundocorradini)
su CodePen.

Non ci sono molti lati negativi in questo, tranne se avete bisogno di supportare i vecchi browser. IE 11 dovrebbe funzionare, ma la sua implementazione di flexbox è piuttosto buggata, quindi dovrebbe essere sempre trattata con molta attenzione. IE 10 richiede un lavoro aggiuntivo in quanto è basato su una vecchia bozza iniziale della specifica che ha una sintassi diversa, e richiede il prefisso del venditore -ms.

9 & 10. Allineare sul grid-container o sul grid-item

CSS Grid include più o meno le stesse opzioni di allineamento di flexbox, quindi possiamo usarlo sul grid-container:

.container{ display: grid; align-items: center; justify-content: center;}

Vedi la penna
Centering 9: align on grid-container di Facundo Corradini (@facundocorradini)
su CodePen.

Oppure solo su una specifica voce della griglia:

.container{ display: grid;}.element{ justify-self: center; align-self: center}

La mancanza di supporto dei browser legacy è l’unica limitazione per questa tecnica.

Vedi la penna
Centering 10: align on grid-item di Facundo Corradini (@facundocorradini)
su CodePen.

Seudo-elementi su una griglia

Similmente all’alternativa flexbox, potremmo usare una griglia a tre file con pseudo-elementi:

.container{ display: grid; grid-template-columns: 1fr; grid-template-rows: repeat(3, 1fr);}.container::before,.container::after{ content:"";}

Ricordate che 1fr significa effettivamente minmax(auto, 1fr), quindi le righe vuote non prenderanno necessariamente un terzo dell’altezza del contenitore. Esse collasseranno come necessario fino al loro valore minimo di auto, e senza contenuto, significa 0.

Vedi la penna
Centering 11 : grid + pseudos di Facundo Corradini (@facundocorradini)
su CodePen.

Questo potrebbe sembrare un approccio sciocco, ma ci permette di mettere facilmente in atto uno dei miei trucchi preferiti di CSS Grid: combinare le righe fr con quelle minmax, che faranno collassare prima le fr vuote, poi quelle mixmax. Jenn Simmons ha grandi esempi in proposito.

Quindi, avere gli pseudos che prendono le righe completamente collassabili permetterà all’algoritmo di auto-placement di fare la sua magia sui nostri elementi reali. Tranne se abbiamo bisogno di supportare IE, che non ha l’auto-placement. Il che ci porta al prossimo metodo…

Posizionamento esplicito delle righe della griglia

La griglia CSS permette agli elementi di essere posizionati esplicitamente su una riga specifica, quindi la stessa dichiarazione della griglia come sopra e l’elemento posizionato sulla seconda riga sarà sufficiente:

.container{ display:grid; grid-template-columns:1fr; grid-template-rows: repeat(3, 1fr);}.element{ grid-row: 2 / span 1; /* or grid-row: 2/3 */}

Questo può funzionare fino a IE10. Che ci crediate o no, IE è stato uno dei primi e più forti sostenitori della griglia CSS, spedendola nel 2011 con IE10. Si basa su una bozza iniziale che ha una sintassi completamente diversa, ma possiamo farla funzionare:

.container{ display: -ms-grid; -ms-grid-rows: (1fr); -ms-grid-columns: 1fr;}.element{ -ms-grid-column: 1; -ms-grid-row: 2;}

Vedi la penna
Centering 12: posizionamento esplicito su una griglia di Facundo Corradini (@facundocorradini)
su CodePen.

Margine automatico su un grid-item

Similmente a flexbox, applicando margin-auto su un grid-item lo si centra su entrambi gli assi.

.container{ display: grid;}.element{ margin: auto;}

Vedi la penna
Centering 12: posizionamento esplicito su una griglia di Facundo Corradini (@facundocorradini)
su CodePen.

Alcune (probabili) implementazioni future

Secondo la specifica CSS Box Alignment Module level 3, align-content dovrebbe funzionare sull’asse dei blocchi dei contenitori a blocchi e dei contenitori multicol, quindi (se i browser lo implementano) dovremmo essere in grado di centrare il contenuto di questi contenitori proprio come facciamo nei contenitori flex o grid.

Prova LogRocket per essere sicuro al 100% che i tuoi elementi siano correttamente centrati

“Sembra buono sulla mia macchina” non è sufficiente. Con LogRocket, potete vedere il DOM (insieme a quei fastidiosi elementi centrati verticalmente) esattamente come fa l’utente finale. Se siete interessati a monitorare e tracciare l’uso della CPU lato client, l’uso della memoria e altro per tutti i vostri utenti in produzione, provate LogRocket.LogRocket Dashboard Free Trial Bannerhttps://logrocket.com/signup/

LogRocket è come un DVR per le applicazioni web, registrando tutto ciò che accade nella vostra applicazione web o sito. Invece di indovinare perché i problemi si verificano, è possibile aggregare e segnalare le metriche chiave delle prestazioni frontend, riprodurre le sessioni utente insieme allo stato dell’applicazione, registrare le richieste di rete e far emergere automaticamente tutti gli errori.

Modernizzare il modo in cui si esegue il debug delle applicazioni web – iniziare il monitoraggio gratuitamente.

Conclusione

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *