Comment centrer le div verticalement à l'intérieur d'un div parent positionné de manière absolue

146

J'essaie d'obtenir un contenant bleu au milieu d'un contenant rose, mais il semble vertical-align: middle;ne pas faire le travail dans ce cas.

<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>

Résultat:

entrez la description de l'image ici

Attente:

entrez la description de l'image ici

Veuillez suggérer comment puis-je y parvenir.

Jsfiddle

Vladimirs
la source
1
Y a-t-il une raison pour laquelle vous utilisez position: absolutepartout?
Vucko le
the vertical-align: middle;works with display: inline-blockor table layout
ctf0
vérifiez ce lien: vanseodesign.com/css/vertical-centering ;)
Jordi Castilla
@Vucko oui - c'est une condition préalable car il ne s'agit que d'une version simplifiée d'une mise en page très complexe, mais la position absolue dans les deux divisions supérieures est la clé.
Vladimirs
@Vladimirs Je ne peux que penser à margin-top: calc((56px - 16px) / 2), où 56px - parent height, 16px - element height/font-size- JSFiddle
Vucko

Réponses:

332

Tout d'abord, notez que cela vertical-alignne s'applique qu'aux cellules de tableau et aux éléments de niveau en ligne.

Il existe plusieurs façons de réaliser des alignements verticaux qui peuvent ou non répondre à vos besoins. Cependant, je vais vous montrer deux méthodes parmi mes préférées:

1. Utilisation transformettop

.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>

Le point clé est qu'une valeur de pourcentage sur topest relative à la heightdu bloc conteneur; Alors qu'une valeur de pourcentage sur transforms est relative à la taille de la boîte elle-même (la boîte englobante).

Si vous rencontrez des problèmes de rendu de police (police floue), le correctif consiste à ajouter perspective(1px)à la transformdéclaration pour qu'elle devienne:

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

Il convient de noter que CSS transform est pris en charge dans IE9 + .

2. Utilisation d' inline-blockéléments (pseudo-)

Dans cette méthode, nous avons deux inline-blockéléments frères qui sont alignés verticalement au milieu par vertical-align: middledéclaration.

L'un d'eux a un heightde 100%son parent et l'autre est notre élément souhaité dont nous voulions l'aligner au milieu.

.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>

Enfin, nous devrions utiliser l'une des méthodes disponibles pour supprimer l'écart entre les éléments de niveau en ligne .

Hashem Qolami
la source
Merci pour ces conseils utiles. Cela fonctionnait pour mon projet. Bon travail.
Sedat Kumcu le
Pour le premier valignélément de méthode devrait êtredisplay: block
Oleg
transform: translateY(-50%);Jamais vu cela auparavant, mais cela fonctionne parfaitement. Véritable économiseur de vie.
Benny Bottema le
55

utilisez ceci :

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

consulter ce lien: https://www.smashingmagazine.com/2013/08/absolute-horizontal-vertical-centering-css/

Điển Trương
la source
En quoi n'est-ce pas la solution principale? Tellement facile et ça marche!
Mason
21
Gardez à l'esprit que la heightpropriété doit être définie (en px, em, etc.) pour que cela fonctionne.
Vaidas
Et si j'ai plusieurs div à l'intérieur du parent? tous ne seraient-ils pas tous placés les uns sur les autres?
psykid
ça ne marche pas s'il y a un autre enfant au même niveau avec "absolu-centre"
Pascut
18

Utilisez flex blox dans votre div positionné de manière absoutement pour centrer son contenu.

Voir l'exemple 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;
}
Chris Aelbrecht
la source
11

Centrer verticalement et horizontalement:

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

Vous pouvez utiliser 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>

G-Cyrillus
la source
Merci, votre exemple fonctionne parfaitement, mais il .bmanque position: absolute;ce qui est important pour afficher d'autres choses que je n'ai pas incluses pour garder le code plus clair. Je sais que cela n'a aucun sens d'avoir une cellule de table positionnée de manière absolue, mais peut-être existe-t-il une autre approche qui permettra de conserver position: absolute;dans les deux .aet les .bclasses?
Vladimirs
si a est une position absolue, et b (l'enfant) lui donnant sa taille, b est lui-même en position absolue par rapport au reste du contenu. sauf si un est supposé rester non dimensionné je ne comprends pas le but de l'absolu à l'intérieur de l'absolu?
G-Cyrillus
1

Voici un moyen simple d'utiliser l'objet Top.

Par exemple: si la taille absolue de l'élément est de 60 px.

.absolute-element { 
    position:absolute; 
    height:60px; 
    top: calc(50% - 60px);
}
Sainul Abid
la source
2
L'utilisation calcest utile, même si cela devrait être top: calc(50% - 30px)pour qu'elle soit réellement centrée.
brainbag
1

Une solution simple supplémentaire

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;  
}
Hicham
la source
0

Veuillez vérifier cette réponse à un problème similaire.

C'est de loin le moyen le plus simple que j'ai trouvé.

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

REMARQUE. J'ai utilisé display: -webkit-flex; au lieu d' affichage: flex; pour tester à l'intérieur de safari.

NOTE DE BAS DE PAGE. Je suis un novice uniquement, partageant l'aide de quelqu'un qui est clairement expérimenté.

Whanau Paitai
la source
0

Vous pouvez le faire en utilisant display:table;dans div parent et display: table-cell; vertical-align: middle;dans div enfant

<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>

Arindam Sarkar
la source
3
il est possible que votre réponse soit bonne mais vous pouvez l'améliorer beaucoup en ajoutant une description de ce que fait votre code ...
DaFois