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


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


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


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/


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

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%);
}

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>


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);
}

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

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


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>


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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.