Perché vertical-align: middle non funziona sul mio span o div?


247

Sto cercando di centrare verticalmente una spano divelemento all'interno di un altro divelemento. Tuttavia quando lo metto vertical-align: middle, non succede nulla. Ho provato a cambiare le displayproprietà di entrambi gli elementi e nulla sembra funzionare.

Questo è quello che sto attualmente facendo nella mia pagina web:

.main {
  height: 72px;
  vertical-align: middle;
  border: 1px solid black;
  padding: 2px;
}
    
.inner {
  vertical-align: middle;
  border: 1px solid red;    
}
    
.second {
  border: 1px solid blue; 
}
<div class="main">
  <div class="inner">
    This box should be centered in the larger box
    <div class="second">Another box in here</div>
  </div>
</div>

Ecco un jsfiddle dell'implementazione che mostra che non funziona: http://jsfiddle.net/gZXWC/

Risposte:


207

Questo sembra essere il modo migliore - è passato del tempo dal mio post originale e questo è ciò che dovrebbe essere fatto ora: http://jsfiddle.net/m3ykdyds/200

/* CSS file */

.main {
    display: table;
}

.inner {
    border: 1px solid #000000;
    display: table-cell;
    vertical-align: middle;
}

/* HTML File */
<div class="main">
    <div class="inner"> This </div>
</div>

2
Quindi, come fa qualcuno a fare ciò che l'OP vuole fare?
— Ryan Mortensen,

Qualche idea su paragrafi a linea variabile? vale a dire. se non c'è modo di sapere se si tratterà di una o due righe. Dovrei quindi utilizzare jQuery?
— Foochow

Cosa succede se l'altezza deve essere dinamica, qual è la soluzione?
— Murhaf Sousli,

non dovrebbe essere la risposta accettata, si basa sulla conoscenza dell'altezza di ".inner", quindi non esattamente quello che l'OP stava chiedendo e alcune risposte molto migliori di seguito vedono le risposte di @timbergus o Tim Perkins in fondo al fondo.
— mike-source,

@ mike-source sapendo che l'altezza di inner è possibile al 100% anche se l'altezza è dinamica poiché un po 'di javascript può capirlo e cambiare dinamicamente la regola CSS per quell'oggetto DOM.
— Charles Addis,

143

Utilizzando CSS3:

<div class="outer">
   <div class="inner"/>
</div>

Css:

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

Nota: questo potrebbe non funzionare nei vecchi IE


16
Questo è supportato da tutti i principali browser moderni e dalla soluzione più semplice e pulita.
— Sam

2
Ricorda inoltre inline-flexdi avere più elementi di fila all'interno dell'elemento interno.
— Dan Nissenbaum,

1
Nel mio caso, poiché volevo centrare il contenuto di .inner anche in orizzontale, ho dovuto aggiungere .inner { width: 100%; }. In questo modo, sembra funzionare come .outer { display: table; } .inner { display: table-cell; vertical-align: middle; }ma senza forzare una larghezza minima.
— Bart S,

Ero solito justify-content: center;allinearmi orizzontalmente, il che funzionava alla grande
— Ruth Young il

140

Prova questo, funziona molto bene per me:

/* 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;

/* W3C */
display:box;
box-pack:center;
box-align:center;

4
risposta eccellente, questo mi ha dato una soluzione completamente funzionante che non ha causato altri problemi a catena (un'app che utilizza jquerymobile + phonegap e tutte le altre soluzioni ha portato a problemi di css e div dimensionamento). Solo per sottolineare che questi parametri devono essere aggiunti a un blocco CSS specifico degli elementi da centrare / mediare, ad esempio: #element span {height:100%;display:-webkit-box;-webkit-box-pack:center;-webkit-box-align:center;}- notare che l'altezza è importante per garantire che lo span erediti l'intera altezza del suo contenitore (probabilmente un div) altrimenti non otterrai ancora la centratura verticale!
— Andy Lorenz,

A proposito, puoi scrivere il codice flexbox standard senza i prefissi del browser e quindi ottenere il prefisso del browser con autoprefixer github.com/postcss/autoprefixer o tramite la demo online simevidas.jsbin.com/gufoko/quiet
— starikovs

2
valore della proprietà non valido boxindisplay
— Joaquinglezsantos,

Inoltre, la risposta di @ user1782556 funziona meglio quando la casella esterna ha un'imbottitura.
— iautomation,

34

Anche l'impostazione dell'altezza della linea alla stessa altezza in cui contiene div funzionerà

DEMO http://jsfiddle.net/kevinPHPkevin/gZXWC/7/

.inner {
    line-height:72px;
    border: 1px solid #000000;
}

1
Ho pubblicato un link che spiega anche questo metodo. Tuttavia, non è il mio metodo preferito, se il resto del layout non ha dimensioni fisse, ho riscontrato problemi con finestre di dimensioni diverse con questo metodo.
— Charles Addis,

2
sì, la tecnica dell'altezza della linea funziona bene, ma SOLO SE hai un contenuto a linea singola. Le linee aggiuntive andranno perse / fuoriusciranno dal contenitore e dovrai ricominciare!
— Andy Lorenz,

a) line-heightcambierà anche l'altezza dell'elemento interno. b) L'elemento interno non è ancora accuratamente centrato verticalmente. c) Non funziona su elementi che non contengono testo, ad esempio: <img>o su elementi con altezza fissa.
— Alph.Dev

Può anche non funzionare su più sistemi operativi (Windows / Mac) a causa delle differenze di rendering dei caratteri
— LocalPCGuy

1
Questo è molto imprevedibile e spesso si traduce in un'altezza aggiuntiva sul contenitore.
— Distruzione

25

Nel caso in cui non si possa fare affidamento su flexbox ... Posizionare .childal .parentcentro. Funziona quando le dimensioni dei pixel sono sconosciute (in altre parole, sempre) e senza problemi anche con IE9 +.

.parent { position: relative; }

.child {
    position: absolute;
    top : 50%;
    left: 50%;
    -ms-transform: translate(-50%, -50%);
    transform    : translate(-50%, -50%);    
}
<div class="parent" style="background:lightyellow; padding:6em"> 
  <div class="child" style="background:gold; padding:1em">&mdash;</div> 
</div>


Questa è in realtà la soluzione più ben fatta, soprattutto dal momento che la maggior parte dei progetti che ho visto finora richiedono la compatibilità IE9
— Jabberwocky,

21

Dovresti mettere vertical-align: middlel'elemento interno, non l'elemento esterno. Impostare la line-heightproprietà sull'elemento esterno in modo che corrisponda a quella heightdell'elemento esterno. Quindi impostare display: inline-blocke line-height: normalsull'elemento interno. In questo modo, il testo sull'elemento interno si avvolgerà con una normale altezza della linea. Funziona su Chrome, Firefox, Safari e IE 8+

.main {
    height: 72px;
    line-height:72px;
    border: 1px solid black;
}
.inner {
    display: inline-block;
    vertical-align: middle;
    line-height: normal;
}
<div class="main">
    <div class="inner">Vertically centered text</div>
</div>

Violino


Questo è probabilmente il modo più semplice ... tutte le altre risposte in questa pagina sono inutilmente ingombranti / hacky O non supportate nei browser più vecchi O fanno affidamento sul conoscere l'altezza dell'elemento interno. In realtà non hai bisogno di line-height: normal;e display:inline;funziona anche. Il vantaggio di questo metodo è che non interferisce con il text-align:center;quale l'utilizzo display: table-cell;può creare problemi. Abbastanza spesso vogliamo allineare sia orizzontalmente che verticalmente. Vedi questo violino modificato: jsfiddle.net/br090prs/36
— mike-source

2
@ mike-source il motivo da utilizzare line-height: normaled display: inline-blockè in modo che il testo interno si avvolga correttamente. Se sei sicuro che il testo nel div interno non andrà mai a capo, queste proprietà non saranno necessarie.
— Tim Perkins,

Da quando Microsoft ha terminato il supporto per le vecchie versioni di IE ho usato flexbox per questo genere di cose (come suggerito da @ user1782556). La mia risposta originale è la strada da percorrere se hai ancora bisogno di supportare IE 10 o precedenti.
— Tim Perkins,

Il 100% è d'accordo, ma non vorrei scegliere personalmente il box flessibile, solo il 76% dei browser lo supporta completamente a partire da maggio 2016 (94% se includi il supporto parziale), vedi: caniuse.com/#search=fLEX% 20box . Si sta avvicinando molto all'essere l'opzione più sensata, a seconda della base di utenti.
— mike-source,

10

L'ho usato per allineare tutto al centro del div wrapper nel caso in cui aiuti chiunque - l'ho trovato più semplice:

div.wrapper {
  /* --- This works --- */
  display: flex;
  /* Align Vertically */
  align-items: center;
  /* Align Horizontally */
  justify-content: center;
  /* --- ---------- ----- */
  width: 100%;
  height:100px;
  background-color: blue;
}
div.inner {
  width: 50px;
  height: 50px;
  background-color: orange;
}
<div class="wrapper">
  <div class="inner">
  </div>
</div>


7

Ecco un esempio di due modi per eseguire un allineamento verticale. Li uso e funzionano abbastanza bene. Uno utilizza il posizionamento assoluto e l'altro utilizza la flexbox .

Esempio di allineamento verticale

Utilizzando Flexbox, è possibile allineare un elemento da solo all'interno di un altro elemento con l' display: flex;utilizzo align-self. Se è necessario allinearlo anche in orizzontale, è possibile utilizzare align-itemse justify-contentnel contenitore.

Se non si desidera utilizzare flexbox, è possibile utilizzare la proprietà position. Se si rende relativo il contenitore e il contenuto assoluto, il contenuto sarà in grado di spostarsi liberamente all'interno del contenitore. Quindi, se si utilizza top: 0;e left: 0;nel contenuto, verrà posizionato nell'angolo in alto a sinistra del contenitore.

Posizionamento assoluto

Quindi, per allinearlo, devi solo cambiare i riferimenti superiore e sinistro al 50%. Ciò posizionerà il contenuto al centro del contenitore dall'angolo in alto a sinistra del contenuto.

Allinea al centro del contenitore

Quindi è necessario correggere questo traducendo il contenuto metà della sua dimensione a sinistra e in alto.

Centrato assoluto


5

ecco un ottimo articolo su come allineare vetic .. Mi piace il modo float.

http://www.vanseodesign.com/css/vertical-centering/

HTML:

<div id="main">
    <div id="floater"></div>
    <div id="inner">Content here</div>
</div>

E lo stile corrispondente:

#main {
   height: 250px;
}

#floater {
   float: left;
   height: 50%;
   width: 100%;
   margin-bottom: -50px;
}

#inner {
   clear: both;
   height: 100px;
}

3
Penso che se si definisce l'altezza del blocco #inner si invalida il concetto di centratura verticale corretta. L'OPS stava chiedendo di renderlo automatico, quindi immagino che ciò significa che l'altezza della scatola interna non è nota al momento del concepimento.
— Alexis Wilke,

5

HTML

<div id="myparent">
  <div id="mychild">Test Content here</div>
</div>

CSS

#myparent {
  display: table;
}
#mychild {
  display: table-cell;
  vertical-align: middle;
}

Impostiamo il div padre da visualizzare come tabella e il div figlio da visualizzare come cella di tabella. Possiamo quindi usare l'allineamento verticale sul div figlio e impostarne il valore al centro. Qualunque cosa all'interno di questo div bambino sarà centrata verticalmente.


4

È semplice. Aggiungi la display:table-celltua classe principale.

.main {
  height: 72px;
  vertical-align: middle;
  display:table-cell;
  border: 1px solid #000000;
}

Dai un'occhiata a questo jsfiddle !


4

Ecco l'ultima soluzione più semplice: non è necessario modificare nulla, è sufficiente aggiungere tre righe di regole CSS al contenitore del div in cui si desidera centrare. Adoro Flex Box#LoveFlexBox

.main {
  /* I changed height to 200px to make it easy to see the alignment. */
  height: 200px;
  vertical-align: middle;
  border: 1px solid #000000;
  padding: 2px;
  
  /* Just add the following three rules to the container of which you want to center at. */
  display: flex;
  flex-direction: column;
  justify-content: center;
  /* This is true vertical center, no math needed. */
}
.inner {
  border: 1px solid #000000;
}
.second {
  border: 1px solid #000000;
}
<div class="main">
  <div class="inner">This box should be centered in the larger box
    <div class="second">Another box in here</div>
  </div>
  <div class="inner">This box should be centered in the larger box
    <div class="second">Another box in here</div>
  </div>
</div>

indennità

il justify-contentvalore può essere impostato sulle seguenti poche opzioni:

  • flex-start, che allineerà il div figlio a dove inizia il flusso flessibile nel suo contenitore principale. In questo caso, rimarrà in cima.

  • center, che allinea il div figlio al centro del contenitore principale. Questo è davvero pulito, perché non è necessario aggiungere un div aggiuntivo per avvolgere tutti i bambini per mettere il wrapper in un contenitore padre per centrare i bambini. Per questo motivo, questo è il vero centro verticale (nello column flex-directionstesso modo, se si cambia flow-directionin row, diventerà centrato orizzontalmente.

  • flex-end, che allineerà il div secondario al punto in cui termina il flusso flessibile nel relativo contenitore principale. In questo caso, si sposterà verso il basso.

  • space-between, che diffonderà tutti i bambini dall'inizio del flusso alla fine del flusso. Se la demo, ho aggiunto un altro div bambino, per mostrare che sono sparsi.

  • space-around, simile a space-between, ma con metà dello spazio all'inizio e alla fine del flusso.


Soluzione perfetta I browser incompatibili possono portare il contenuto non allineato e l'utente deve gestirlo o aggiornare il proprio browser.
— volte il

0

Da vertical-align funziona come previsto su a td, è possibile inserire una singola cella tablein divper allineare il suo contenuto.

<div>
    <table style="width: 100%; height: 100%;"><tr><td style="vertical-align: middle; text-align: center">
        Aligned content here...
    </td></tr></table>
</div>

Clunky, ma funziona per quanto posso dire. Potrebbe non avere gli svantaggi delle altre soluzioni alternative.


5
No, per favore, niente più tavoli. CSS può farlo in modo pulito. Non è necessario utilizzare <table> in questo caso.
— enguerranws,

0

Inserisci il contenuto in una tabella con altezza del 100% e imposta l'altezza per il div principale

<div style="height:80px;border: 1px solid #000000;">
<table style="height:100%">
<tr><td style="vertical-align: middle;">
  This paragraph should be centered in the larger box
</td></tr>
</table>
</div>

0

Per centrare verticalmente una campata o un elemento div all'interno di un altro div, aggiungere la posizione relativa al div parent e la posizione assoluta al div figlio. Ora il div figlio può essere posizionato in qualsiasi punto all'interno del div. Esempio sotto i centri sia in orizzontale che in verticale.

<div class="parent">
    <div class="child">Vertically and horizontally centered child div</div>
</div>

css:

.parent{
    position: relative;
}
.child{
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    margin: auto;
}

0

Questo è un approccio moderno e utilizza la funzionalità CSS Flexbox. Ora puoi allineare verticalmente il contenuto all'interno del tuo contenitore principale semplicemente aggiungendo questi stili al .maincontenitore

.main {
        display: flex;
        flex-direction: column;
        justify-content: center;
}

E sei a posto!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.