Pourquoi l'alignement vertical: le milieu ne fonctionne pas sur mon span ou div?

246

J'essaie de centrer verticalement un élément spanou divdans un autre divélément. Cependant quand je mets vertical-align: middle, rien ne se passe. J'ai essayé de changer les displaypropriétés des deux éléments, et rien ne semble fonctionner.

Voici ce que je fais actuellement sur ma page 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>

Voici un jsfiddle de l'implémentation montrant que cela ne fonctionne pas: http://jsfiddle.net/gZXWC/

Brad
la source

Réponses:

207

Cela semble être le meilleur moyen - un certain temps s'est écoulé depuis mon message d'origine et c'est ce qui devrait être fait maintenant: 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>
Charles Addis
la source
2
Alors, comment fait-on ce que le PO veut faire?
Ryan Mortensen
Des idées sur les paragraphes à lignes variables? c'est à dire. s'il n'y a aucun moyen de savoir si ce sera une ou deux lignes. Aurais-je alors besoin d'utiliser jQuery?
foochow
Et si la hauteur doit être dynamique, quelle est la solution?
Murhaf Sousli
ne devrait pas être la réponse acceptée, repose sur la connaissance de la hauteur du ``.
mike-source
@ mike-source sachant que la hauteur de l'intérieur est 100% possible même si la hauteur est dynamique car un peu de javascript peut comprendre cela et changer dynamiquement la règle CSS pour cet objet DOM.
Charles Addis
143

Utilisation de CSS3:

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

Css:

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

Remarque: cela peut ne pas fonctionner dans les anciens IE

user1782556
la source
16
Ceci est pris en charge par tous les principaux navigateurs modernes et par la solution la plus simple et la plus propre.
Sam
2
Gardez également à l'esprit inline-flexd'avoir plusieurs éléments d'affilée à l'intérieur de l'élément intérieur.
Dan Nissenbaum
1
Dans mon cas, comme je voulais également centrer le contenu de .inner horizontalement, j'ai dû ajouter .inner { width: 100%; }. De cette façon, il semble fonctionner comme .outer { display: table; } .inner { display: table-cell; vertical-align: middle; }mais sans forcer une largeur minimale.
Bart S
J'avais l'habitude justify-content: center;d'aligner horizontalement ce qui fonctionnait très bien
Ruth Young
140

Essayez ceci, fonctionne très bien pour moi:

/* 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;
Mahendra Liya
la source
4
excellente réponse, cela m'a donné une solution pleinement fonctionnelle qui n'a pas causé d'autres problèmes (une application utilisant jquerymobile + phonegap et toutes les autres solutions a conduit à des problèmes de dimensionnement css & div). Juste pour souligner que ces paramètres doivent être ajoutés à un bloc CSS spécifique aux éléments à centrer / middled, par exemple: #element span {height:100%;display:-webkit-box;-webkit-box-pack:center;-webkit-box-align:center;}- notez que la hauteur est importante pour garantir que la travée hérite de la pleine hauteur de son conteneur (probablement un div) sinon vous n'obtiendrez toujours pas le centrage vertical!
Andy Lorenz
BTW, vous pouvez écrire du code Flexbox standard sans préfixe de navigateur, puis obtenir le préfixe du navigateur avec autoprefixer github.com/postcss/autoprefixer ou via la démo en ligne simevidas.jsbin.com/gufoko/quiet
starikovs
2
valeur de propriété non valide boxdansdisplay
Joaquinglezsantos
De plus, la réponse de @ user1782556 fonctionne mieux lorsque la boîte extérieure a un rembourrage.
iautomation
34

La définition de la hauteur de ligne à la même hauteur qu'elle contient div fonctionnera également

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

.inner {
    line-height:72px;
    border: 1px solid #000000;
}
Kevin Lynch
la source
1
J'ai également publié un lien expliquant cette méthode. Pas ma méthode préférée cependant, si le reste de la mise en page n'est pas de taille fixe - j'ai rencontré des problèmes sur des fenêtres de tailles différentes avec cette méthode.
Charles Addis
2
oui, la technique de hauteur de ligne fonctionne bien, mais UNIQUEMENT SI vous avez du contenu sur une seule ligne. Des lignes supplémentaires seront perdues / déborderont à l'extérieur du conteneur et vous devrez recommencer!
Andy Lorenz
a) line-heightchangera également la hauteur de l'élément intérieur. b) L'élément intérieur n'est toujours pas centré verticalement avec précision. c) Il ne fonctionne pas sur les éléments qui ne contiennent pas de texte, par exemple:, <img>ou les éléments à hauteur fixe.
Alph.Dev
Il peut également échouer entre les systèmes d'exploitation (Windows / Mac) en raison de différences de rendu des
polices
1
Ceci est très imprévisible et se traduit souvent par une hauteur supplémentaire sur le conteneur.
Undistraction
25

Dans le cas où vous ne pouvez pas compter sur Flexbox ... Placer .childau .parentcentre de. Fonctionne lorsque la taille des pixels est inconnue (en d'autres termes, toujours) et qu'il n'y a pas de problème avec IE9 + également.

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

kornieff
la source
C'est en fait la solution la plus
Jabberwocky
20

Vous devez mettre vertical-align: middlel'élément intérieur, pas l'élément extérieur. Définissez la line-heightpropriété sur l'élément externe pour qu'elle corresponde à celle heightde l'élément externe. Ensuite, placez display: inline-blocket line-height: normalsur l'élément intérieur. En faisant cela, le texte sur l'élément interne se terminera par une hauteur de ligne normale. Fonctionne dans Chrome, Firefox, Safari et 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>

Violon

Tim Perkins
la source
C'est probablement le moyen le plus simple ... toutes les autres réponses sur cette page sont inutilement maladroites / hacky OU ne sont pas prises en charge dans les anciens navigateurs OU reposent sur la connaissance de la hauteur de l'élément intérieur. Vous n'avez pas vraiment besoin du line-height: normal;et ça display:inline;marche aussi. Le bonus de cette méthode est qu'elle n'interfère pas avec text-align:center;laquelle l'utilisation display: table-cell;peut créer des problèmes. Très souvent, nous voulons aligner aussi bien horizontalement que verticalement. Voir ce violon édité: jsfiddle.net/br090prs/36
mike-source
2
@ mike-source la raison de l'utilisation line-height: normalet display: inline-blockest pour que le texte interne soit correctement encapsulé. Si vous êtes sûr que le texte dans la div intérieure ne sera jamais bouclé, ces propriétés ne seront pas nécessaires.
Tim Perkins
Depuis que Microsoft a mis fin à la prise en charge des anciennes versions d'IE, j'ai utilisé flexbox pour ce genre de chose (comme l'a suggéré @ user1782556). Ma réponse originale est la voie à suivre si vous devez toujours prendre en charge IE 10 ou une version antérieure.
Tim Perkins
100% d'accord, mais je n'opterais pas personnellement pour la boîte flexible pour l'instant, seulement 76% des navigateurs la prennent entièrement en charge en mai 2016 (94% si vous incluez une assistance partielle), voir: caniuse.com/#search=flexible% 20box . Cependant, cela devient très proche d'être l'option la plus judicieuse, en fonction de votre base d'utilisateurs.
mike-source
10

Je l'ai utilisé pour aligner tout au centre de la div enveloppe au cas où cela aiderait quelqu'un - je l'ai trouvé le plus simple:

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>

Ruth Young
la source
7

Voici un exemple de deux façons de faire un alignement vertical. Je les utilise et ils fonctionnent plutôt bien. L'un utilise le positionnement absolu et l'autre utilise la flexbox .

Exemple d'alignement vertical

En utilisant flexbox, vous pouvez aligner un élément par lui-même à l'intérieur d'un autre élément avec display: flex;using align-self. Si vous devez l'aligner également horizontalement, vous pouvez utiliser align-itemset justify-contentdans le conteneur.

Si vous ne souhaitez pas utiliser flexbox, vous pouvez utiliser la propriété position. Si vous rendez le conteneur relatif et le contenu absolu, le contenu pourra se déplacer librement à l'intérieur du conteneur. Donc, si vous utilisez top: 0;et left: 0;dans le contenu, il sera positionné dans le coin supérieur gauche du conteneur.

Positionnement absolu

Ensuite, pour l'aligner, il vous suffit de modifier les références supérieure et gauche à 50%. Cela positionnera le contenu au centre du conteneur à partir du coin supérieur gauche du contenu.

Alignez au milieu du conteneur

Vous devez donc corriger cela en traduisant le contenu de la moitié de sa taille vers la gauche et le haut.

Absolue centrée

Timbergus
la source
5

voici un excellent article sur la façon d'aligner vical .. J'aime la façon de flotter.

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

Le HTML:

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

Et le style correspondant:

#main {
   height: 250px;
}

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

#inner {
   clear: both;
   height: 100px;
}
Dory Zidon
la source
3
Je pense que si vous définissez la hauteur du bloc #inner, cela invalide le concept de centrage vertical approprié. L'OPS demandait de le rendre automatique, donc j'imagine que cela signifie que la hauteur de la boîte intérieure n'est pas connue au moment de la conception.
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;
}

Nous avons défini le div parent pour qu'il s'affiche sous forme de tableau et le div enfant pour qu'il s'affiche sous forme de cellule de tableau. Nous pouvons ensuite utiliser l'alignement vertical sur le div enfant et définir sa valeur au milieu. Tout ce qui se trouve à l'intérieur de cette division enfant sera centré verticalement.

Brijesh Patel
la source
4

C'est simple. Ajoutez simplement display:table-cellvotre classe principale.

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

Découvrez ce jsfiddle !

RizonBarns
la source
4

Voici la dernière solution la plus simple - pas besoin de changer quoi que ce soit, ajoutez simplement trois lignes de règles CSS à votre conteneur de div où vous souhaitez vous centrer. J'adore 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>

Prime

la justify-contentvaleur peut être réglée sur les quelques options suivantes:

  • flex-start, qui alignera la division enfant à l'endroit où le flux flexible commence dans son conteneur parent. Dans ce cas, il restera au top.

  • center, qui alignera le div enfant sur le centre de son conteneur parent. C'est vraiment bien, car vous n'avez pas besoin d'ajouter un div supplémentaire pour envelopper tous les enfants pour mettre le wrapper dans un conteneur parent pour centrer les enfants. Pour cette raison, c'est le vrai centre vertical (dans le column flex-direction. De même, si vous changez le flow-directionen row, il deviendra centré horizontalement.

  • flex-end, qui alignera la division enfant à l'endroit où le flux flexible se termine dans son conteneur parent. Dans ce cas, il se déplacera vers le bas.

  • space-between, qui répartira tous les enfants du début du flux à la fin du flux. Si la démo, j'ai ajouté un autre div enfant, pour montrer qu'ils sont répartis.

  • space-around, similaire à space-between, mais avec la moitié de l'espace au début et à la fin du flux.

Downhillski
la source
Solution parfaite. Les navigateurs incompatibles peuvent prendre le contenu non aligné et l'utilisateur doit le traiter ou mettre à niveau son navigateur.
twicejr
0

Puisque vertical-alignfonctionne comme prévu sur un td, vous pouvez mettre une seule cellule tabledans le divpour aligner son contenu.

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

Clunky, mais fonctionne pour autant que je sache. Il pourrait ne pas avoir les inconvénients des autres solutions de contournement.

Smig
la source
5
Non, je vous en prie, plus de tables. CSS peut le faire d'une manière propre. Il n'est pas nécessaire d'utiliser <table> dans ce cas.
enguerranws
0

Placez simplement le contenu dans un tableau avec une hauteur de 100% et définissez la hauteur du div principal

<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>
Ramiro Mosquera
la source
0

Pour centrer verticalement un élément span ou div dans un autre div, ajoutez la position relative au div parent et la position absolue à la div enfant. Maintenant, la div enfant peut être positionnée n'importe où à l'intérieur de la div.

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

Il s'agit d'une approche moderne et elle utilise la fonctionnalité CSS Flexbox. Vous pouvez maintenant aligner verticalement le contenu dans votre conteneur parent en ajoutant simplement ces styles au .mainconteneur

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

Et vous êtes prêt à partir!

Kingsley Gyimah
la source