Come centrare il div verticalmente all'interno del div parent posizionato in modo assoluto


146

Sto cercando di ottenere un contenitore blu nel mezzo di quello rosa, tuttavia sembra vertical-align: middle;che in quel caso non funzioni.

<div style="display: block; position: absolute; left: 50px; top: 50px;">
    <div style="text-align: left; position: absolute;height: 56px;vertical-align: middle;background-color: pink;">
        <div style="background-color: lightblue;">test</div>
    </div>
</div>

Risultato:

inserisci qui la descrizione dell'immagine

aspettative:

inserisci qui la descrizione dell'immagine

Per favore, suggerisci come posso farlo.

Jsfiddle


1
C'è un motivo per cui stai usando position: absolutedappertutto?
Vucko,

le vertical-align: middle;opere con display: inline-blocko layout del tavolo
ctf0


@Vucko sì - questo è un prerequisito in quanto questa è solo una versione semplificata di layout molto complesso, ma la posizione assoluta in entrambi i migliori div è la cosa chiave.
Vladimirs,

@Vladimirs Mi viene solo in mente margin-top: calc((56px - 16px) / 2), dove 56px - parent height, 16px - element height/font-size- JSFiddle
Vucko,

Risposte:


332

Prima di tutto, nota che vertical-alignè applicabile solo alle celle di tabella e agli elementi di livello inline.

Esistono due modi per ottenere allineamenti verticali che possono o meno soddisfare le tue esigenze. Tuttavia ti mostrerò due metodi dai miei preferiti:

1. Utilizzo di transformetop

.valign {
    position: relative;
    top: 50%;
    transform: translateY(-50%);
    /* vendor prefixes omitted due to brevity */
}
<div style="position: absolute; left: 50px; top: 50px;">
    <div style="text-align: left; position: absolute;height: 56px;background-color: pink;">
        <div class="valign" style="background-color: lightblue;">test</div>
    </div>
</div>

Il punto chiave è che un valore percentuale su topè relativo al heightblocco contenente; Mentre un valore percentuale su transforms è relativo alla dimensione del riquadro stesso (il riquadro di delimitazione).

Se si verificano problemi di rendering dei caratteri (carattere sfocato), la correzione è quella di aggiungere perspective(1px)alla transformdichiarazione in modo che diventi:

transform: perspective(1px) translateY(-50%);

Vale la pena notare che CSS transform è supportato in IE9 + .

2. Utilizzo di inline-block(pseudo-) elementi

In questo metodo, abbiamo due inline-blockelementi fratelli che sono allineati verticalmente al centro dalla vertical-align: middledichiarazione.

Uno di questi ha uno heightdei 100%suoi genitori e l'altro è l'elemento desiderato di cui volevamo allinearlo al centro.

.parent {
    text-align: left;
    position: absolute;
    height: 56px;
    background-color: pink;
    white-space: nowrap;
    font-size: 0; /* remove the gap between inline level elements */
}

.dummy-child { height: 100%; }

.valign {
    font-size: 16px; /* re-set the font-size */
}

.dummy-child, .valign {
    display: inline-block;
    vertical-align: middle;
}
<div style="position: absolute; left: 50px; top: 50px;">
    <div class="parent">
        <div class="dummy-child"></div>
        <div class="valign" style="background-color: lightblue;">test</div>
    </div>
</div>

Infine, dovremmo utilizzare uno dei metodi disponibili per rimuovere il divario tra elementi a livello di inline .


Grazie per questi utili suggerimenti. Funzionava per il mio progetto. Buon lavoro.
Sedat Kumcu

Per il primo valignelemento del metodo dovrebbe esseredisplay: block
Oleg

transform: translateY(-50%);Non l'ho mai visto prima, ma funziona perfettamente. Risparmio di vita reale.
Benny Bottema,

55

Usa questo :

.Absolute-Center {
    margin: auto;
    position: absolute;
    top: 0; left: 0; bottom: 0; right: 0;
}

fai riferimento a questo link: https://www.smashingmagazine.com/2013/08/absolute-horizontal-vertical-centering-css/


In che modo questa non è la soluzione principale? Così facile e funziona!
Mason,

21
Tieni presente che la heightproprietà deve essere definita (in px, em, ecc.) Affinché funzioni.
Vaidas,

Cosa succede se ho più div all'interno del genitore? non sarebbero tutti posizionati uno sopra l'altro?
psykid,

non funziona se c'è un altro bambino sullo stesso livello con "centro assoluto"
Pascut,

18

Usa flex blox nel tuo div posizionato in modo abituale per centrare il suo contenuto.

Vedi esempio https://plnkr.co/edit/wJIX2NpbNhO34X68ZyoY?p=preview

.some-absolute-div {    
  display: -webkit-box;
  display: -webkit-flex;
  display: -moz-box;
  display: -moz-flex;
  display: -ms-flexbox;
  display: flex;

  -webkit-box-pack: center;
  -ms-flex-pack: center;
  -webkit-justify-content: center;
  -moz-justify-content: center;
  justify-content: center;

  -webkit-box-align: center;
  -ms-flex-align: center;
  -webkit-align-items: center;
  -moz-align-items: center;
  align-items: center;
}

11

Centra verticalmente e orizzontalmente:

.parent{
  height: 100%;
  position: absolute;
  width: 100%;
  top: 0;
  left: 0;
}
.c{
  position: absolute;
  top: 50%;
  left: 0;
  right: 0;
  transform: translateY(-50%);
}

3

Puoi usare display:table/table-cell;

.a{
   position: absolute; 
  left: 50px; 
  top: 50px;
  display:table;
}
.b{
  text-align: left; 
  display:table-cell;
  height: 56px;
  vertical-align: middle;
  background-color: pink;
}
.c {
  background-color: lightblue;
}
<div class="a">
  <div  class="b">
    <div class="c" >test</div>
  </div>
</div>


Grazie, il tuo esempio funziona perfettamente, anche se .bmancante position: absolute;è importante per visualizzare altre proprietà che non ho incluso per mantenere il codice più chiaro. So che non ha senso avere una cella di tabella posizionata in modo assoluto, ma forse c'è un altro approccio che permetterà di mantenere position: absolute;sia in classe .ache in .bclasse?
Vladimirs,

se a è la posizione assoluta e b (il bambino) dandogli la sua dimensione, b è essa stessa in posizione assoluta rispetto al resto del contenuto. a meno che a non si supponga di rimanere non dimensionato, non capisco lo scopo dell'assoluto dentro l'assoluto?
G-Cyrillus,

1

Ecco un modo semplice per utilizzare l'oggetto Top.

es: se la dimensione assoluta dell'elemento è 60px.

.absolute-element { 
    position:absolute; 
    height:60px; 
    top: calc(50% - 60px);
}

2
L'uso calcè utile, anche se questo dovrebbe essere top: calc(50% - 30px)per essere effettivamente centrato.
brainbag,

1

Un'ulteriore soluzione semplice

HTML:

<div id="d1">
    <div id="d2">
        Text
    </div>
</div>

CSS:

#d1{
    position:absolute;
    top:100px;left:100px;
}

#d2{
    border:1px solid black;
    height:50px; width:50px;
    display:table-cell;
    vertical-align:middle;
    text-align:center;  
}

0

Controlla questa risposta a un problema simile.

Questo è di gran lunga il modo più semplice che ho trovato.

https://stackoverflow.com/a/26079837/4593442

NOTA. Ho usato display: -webkit-flex; invece di display: flex; per i test all'interno di Safari.

NOTA. Sono solo un principiante, condividendo l'aiuto di qualcuno che ha chiaramente esperienza.


0

Puoi farlo utilizzando display:table;in div genitore e display: table-cell; vertical-align: middle;in div figlio

<div style="display:table;">
      <div style="text-align: left;  height: 56px;  background-color: pink; display: table-cell; vertical-align: middle;">
          <div style="background-color: lightblue; ">test</div>
      </div>
  </div>


3
è possibile che la tua risposta sia buona ma puoi migliorarla molto aggiungendo una descrizione di ciò che fa il tuo codice ...
DaFois
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.