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.