Aligner verticalement le texte à côté d'une image?

1967

Pourquoi ne vertical-align: middlemarche pas ? Et pourtant, vertical-align: top ça marche.

span{
  vertical-align: middle;
}
<div>
  <img src="http://lorempixel.com/30/30/" alt="small img" />
  <span>Doesn't work.</span>
</div>

sam
la source
12
Voici un article intéressant: Comprendrevertical-align
Phaedrus

Réponses:

2253

En fait, dans ce cas, c'est assez simple: appliquez l'alignement vertical à l'image. Comme tout est sur une seule ligne, c'est vraiment l'image que vous souhaitez aligner, pas le texte.

<!-- moved "vertical-align:middle" style from span to img -->
<div>
  <img style="vertical-align:middle" src="https://placehold.it/60x60">
  <span style="">Works.</span>
</div>

Testé en FF3.

Vous pouvez maintenant utiliser flexbox pour ce type de mise en page.

.box {
   display: flex;
   align-items:center;
}
<div class="box">
    <img src="https://placehold.it/60x60">
    <span style="">Works.</span>
</div>

Michael Haren
la source
188
"Comme tout est sur une seule ligne, c'est vraiment l'image que vous voulez aligner, pas le texte." - Non, l'image est bien là où elle est. Nous voulons que le texte soit aligné. Pas l'image. - Je comprends que cela fonctionne (dans certaines circonstances, ex: lorsque vous n'utilisez pas "float: left" sur l'image ...), mais c'est juste bizarre et peu intuitif que de déplacer physiquement le texte vers le milieu vertical, vous devrait appliquer un attribut à l'image à côté de lui à la place.
BrainSlugs83
35
@ BrainSlug83 Ce n'est certainement pas bizarre, mais je peux voir comment les nouveaux arrivants peuvent être gênés par cela. Par défaut, une image sera placée sur la ligne de base du texte. Tout ce que vous faites, c'est déplacer l'endroit où l'image est attachée par rapport au texte. Quant à l'utilisation de float: left, vous devriez le faire soit sur le bloc qui contient l'image et le texte, soit sur le texte lui-même.
jamesrom
14
@ BrainSlugs83 Convenu qu'il peut être considéré comme contre-intuitif. Cela prend un peu de décalage mental, car selon CSS, ce que vous devez faire est de centrer l'image sur le texte. Pas le texte de l'image.
Greg Pettit
6
Cela ne fonctionne pas si vous augmentez la spantaille de la police. Voir ma réponse .
Mori
2
Mais si vous définissez une taille d'image plus petite (comme width:16px;height:16px), vous pouvez voir que l'image sera trop basse ...
Matthieu Charbonnier
340

Voici quelques techniques simples d'alignement vertical:

Alignement vertical sur une ligne: milieu

Celui-ci est simple: définissez la hauteur de ligne de l'élément de texte sur celle du conteneur

<div>
  <img style="width:30px; height:30px;">
  <span style="line-height:30px;">Doesn't work.</span>
</div>

Alignement vertical sur plusieurs lignes: en bas

Positionner absolument une div intérieure par rapport à son conteneur

<div style="position:relative;width:30px;height:60px;">
  <div style="position:absolute;bottom:0">This is positioned on the bottom</div>
</div>

Alignement vertical sur plusieurs lignes: milieu

<div style="display:table;width:30px;height:60px;">
  <div style="display:table-cell;height:30px;">This is positioned in the middle</div>
</div>

Si vous devez prendre en charge les anciennes versions d'IE <= 7

Pour que cela fonctionne correctement dans tous les domaines, vous devrez pirater un peu le CSS. Heureusement, il existe un bug IE qui fonctionne en notre faveur. En plaçant top:50%sur le récipient et top:-50%sur la div intérieure, vous pouvez obtenir le même résultat. Nous pouvons combiner les deux en utilisant une autre fonctionnalité qu'IE ne prend pas en charge: les sélecteurs CSS avancés.

<style type="text/css">
  #container {
    width: 30px;
    height: 60px;
    position: relative;
  }
  #wrapper > #container {
    display: table;
    position: static;
  }
  #container div {
    position: absolute;
    top: 50%;
  }
  #container div div {
    position: relative;
    top: -50%;
  }
  #container > div {
    display: table-cell;
    vertical-align: middle;
    position: static;
  }
</style>

<div id="wrapper">
  <div id="container">
    <div><div><p>Works in everything!</p></div></div>
  </div>
</div>

Alignement vertical à hauteur variable du conteneur: milieu

Cette solution nécessite un navigateur légèrement plus moderne que les autres solutions, car elle utilise la transform: translateYpropriété. ( http://caniuse.com/#feat=transforms2d )

L'application des 3 lignes CSS suivantes à un élément le centrera verticalement dans son parent, quelle que soit la hauteur de l'élément parent:

position: relative;
top: 50%;
transform: translateY(-50%);
Adam Lassek
la source
15
Les sélecteurs display:tableet display:table-cellCSS fonctionnent très bien, sauf, bien sûr, dans IE7 et ci-dessous. Après m'être arraché les cheveux pendant plusieurs heures, j'ai décidé que je n'avais pas vraiment besoin de m'occuper de quelqu'un qui utilisait encore IE7-.
banncee
2
display:tablea quelques limitations dans divers navigateurs (dans IE11 max-heightne fonctionne pas si l'élément est à l'intérieur d'une cellule de tableau), donc dans certains cas extrêmes , ce n'est pas une bonne idée de s'aligner verticalement en utilisant des cellules de tableau.
jahu
97

Changez votre diven un conteneur flexible:

div { display:flex; }


Il existe maintenant deux méthodes pour centrer les alignements pour tout le contenu:

Méthode 1:

div { align-items:center; }

DEMO


Méthode 2:

div * { margin-top:auto; margin-bottom:auto; }

DEMO


Essayez différentes valeurs de largeur et de hauteur sur le imget différentes valeurs de taille de police sur le spanet vous verrez qu'elles restent toujours au milieu du conteneur.

Mori
la source
Afin de centrer le texte à côté ou entre les images (horizontalement sur la page), vous devez également ajouter justify-content: center;et pour l'espacement (sans utiliser de balises <br/>), vous pouvez également ajouter un padding: 1em;. Grande mise à jour pour nous, développeurs de navigateurs modernes.
CSS
Cela a bien fonctionné. J'ai essayé chacune et chacune des autres réponses, et même si elles fonctionnaient dans une certaine mesure, cela n'a pas fonctionné pour moi. J'avais environ 3 lignes de texte à aligner, et cette réponse a parfaitement fonctionné. Merci @Mori
semaj0
87

Vous devez appliquer vertical-align: middleaux deux éléments pour qu'il soit parfaitement centré.

<div>
  <img style="vertical-align:middle" src="http://lorempixel.com/60/60/">
  <span style="vertical-align:middle">Perfectly centered</span>
</div>

La réponse acceptée centre l'icône autour de la moitié de la hauteur x du texte à côté (comme défini dans les spécifications CSS ). Ce qui pourrait être assez bon mais peut sembler un peu différent, si le texte a des ascendants ou des descendants se détachant juste en haut ou en bas:

comparaison d'icônes centrées

À gauche, le texte n'est pas aligné, à droite, comme indiqué ci-dessus. Une démonstration en direct peut être trouvée dans cet article sur l'alignement vertical .

Quelqu'un a-t-il expliqué pourquoi vertical-align: topfonctionnait dans le scénario? L'image dans la question est probablement plus haute que le texte et définit ainsi le bord supérieur de la zone de ligne. vertical-align: topsur l'élément span puis le positionne simplement en haut de la zone de ligne.

La principale différence de comportement entre vertical-align: middleet topest que le premier déplace les éléments par rapport à la ligne de base de la boîte (qui est placée là où cela est nécessaire pour remplir tous les alignements verticaux et se sent donc plutôt imprévisible ) et la seconde par rapport aux limites extérieures de la boîte de ligne (qui est plus tangible).

christopheraue
la source
1
J'ai remarqué des travaux en haut et en bas, mais pas au milieu. Fondamentalement, le «milieu» n'est pas défini comme à mi-chemin entre le haut et le bas. Cela signifie plus "quand il est plus grand que le texte, tenez-vous également dans les deux sens". Et ici, vous n'avez pas besoin d'alignement vertical: du milieu sur le texte, juste l'image.
Curtis
61

La technique utilisée dans la réponse acceptée ne fonctionne que pour le texte à ligne simple ( démo ), mais pas le texte à plusieurs lignes ( démo ) - comme indiqué ici.

Si quelqu'un a besoin de centrer verticalement du texte à plusieurs lignes sur une image, voici quelques façons (méthodes 1 et 2 inspirées de cet article CSS-Tricks )

Méthode n ° 1: tables CSS ( FIDDLE ) (IE8 + ( caniuse ))

CSS:

div {
    display: table;
}
span {
    vertical-align: middle;
    display: table-cell;
}

Méthode n ° 2: pseudo-élément sur le conteneur ( FIDDLE ) (IE8 +)

CSS:

div {
   height: 200px; /* height of image */
}

div:before {
  content: '';
  display: inline-block;
  height: 100%;
  vertical-align: middle;
  margin-right: -0.25em; /* Adjusts for spacing */
}

img {
    position: absolute;
}

span {
  display: inline-block;
  vertical-align: middle;
  margin-left: 200px;  /* width of image */
}

Méthode n ° 3: Flexbox ( FIDDLE ) ( caniuse )

CSS (le violon ci-dessus contient des préfixes de fournisseurs):

div {   
    display: flex; 
    align-items: center;    
}
img {
    min-width: 200px; /* width of image */
}
Danield
la source
3
Les méthodes fonctionnent bien si l'image est plus grande (en hauteur) que le texte. Mais si l'image est plus petite, tout sauf la dernière échoue malheureusement
Thomas
28

Ce code fonctionne aussi bien dans IE que dans FF:

<div>
  <img style="width:auto; height:auto;vertical-align: middle;">
  <span>It does work on all browsers</span>
</div>
HTMLnewBie
la source
19

Parce que vous devez régler la line-heighthauteur du div pour que cela fonctionne

Ikke
la source
2
J'ai essayé de régler la hauteur de ligne à 30 pixels et cela ne fonctionne toujours pas.
sam
12

Fondamentalement, vous devrez passer à CSS3.

-moz-box-align: center;
-webkit-box-align: center;
Dan
la source
11

Pour mémoire, les "commandes" d'alignement ne devraient pas fonctionner sur un SPAN, car il s'agit d'une balise en ligne , pas d'une balise de niveau bloc . Des choses comme l'alignement, la marge, le remplissage, etc. ne fonctionneront pas sur une balise en ligne, car le point d'inline n'est pas de perturber le flux de texte.

CSS divise les balises HTML en deux groupes: en ligne et au niveau du bloc. Recherchez "css block vs inline" et un excellent article apparaît ...

http://www.webdesignfromscratch.com/html-css/css-block-and-inline/

(Comprendre les principes CSS de base est la clé pour qu'il ne soit pas si ennuyeux)

David
la source
2
text-alignet vertical-align(à l'exception de son application sur des tdéléments à des fins patrimoniales) sont spécifiquement destinés à inlineet inline-blockéléments ( span, img, etc.).
Kevin Peno
11

Utilisez line-height:30pxpour la portée de sorte que le texte soit aligné avec l'image:

<div>
  <img style="width:30px; height:30px;">
  <span style="line-height:30px;">Doesn't work.</span>
</div>
Touhid Rahman
la source
11

Une autre chose que vous pouvez faire est de définir le texte line-heightà la taille des images dans le <div>. Réglez ensuite les images survertical-align: middle;

C'est vraiment le moyen le plus simple.

nullpoint81
la source
3
Notez que cela ne fonctionne pas correctement si votre contenu est réparti sur plusieurs lignes.
Ahmad Alfy
et pourquoi pas seulement la hauteur de ligne: 100%?
Jean Paul AKA el_vete
8

Je n'ai pas encore trouvé de solution margindans aucune de ces réponses, alors voici ma solution à ce problème.

Cette solution ne fonctionne que si vous connaissez la largeur de votre image.

Le HTML

<div>
    <img src="https://placehold.it/80x80">
    <span>This is my very long text what should align. This is my very long text what should align.</span>
</div>

Le CSS

div {
  overflow:hidden;
}
img {
   width:80px
   margin-right:20px;
   display:inline-block;
   vertical-align:middle;
}
span {
   width:100%;
   margin-right:-100px;
   padding-right:100px;
   display:inline-block;
   vertical-align:middle;
   box-sizing:border-box;
   -moz-box-sizing:border-box;
   -webkit-box-sizing:border-box;
}
Fleuv
la source
1
Voici la solution exacte. Cela fonctionne aussi pour les textes multilignes ... Les exemples ci-dessus ne conviennent pas aux lignes multiples.
efirat
6
background:url(../images/red_bullet.jpg) left 3px no-repeat;

J'utilise généralement 3px à la place de top. En augmentant / diminuant cette valeur, l'image peut être modifiée à la hauteur requise.

AspiringCanadian
la source
N'aide pas dans les situations où la taille de l'image est inconnue ou dynamique.
Dan
6

Écrivez ces propriétés de portée

span{
    display:inline-block;
    vertical-align:middle;
}

Utiliser display:inline-block;lorsque vous utilisez une vertical-alignpropriété. Ce sont des propriétés associées

Mr.Pandya
la source
6

Vous pouvez définir l'image comme inline elementutilisant la displaypropriété

<div>
  <img style="vertical-align: middle; display: inline;" src="https://placehold.it/60x60">
  <span style="vertical-align: middle; display: inline;">Works.</span>
</div>

Super utilisateur
la source
3

Sur un bouton dans jQuery mobile, par exemple, vous pouvez le modifier un peu en appliquant ce style à l'image:

.btn-image {
    vertical-align:middle;
    margin:0 0 3px 0;
}
den232
la source
2

Solution multiligne:

http://jsfiddle.net/zH58L/6/

<div style="display:table;width:30px;height:160px;">
    <img style="display:table-cell;width:30px;height:60px;padding:50px" src='...' />
    <div style="display:table-cell;height:30px;vertical-align:middle">
      Multiline text centered vertically
    </div>
</div>
<!-- note: img (height + 2x padding) must be equal to root div height -->

Fonctionne dans tous les browers et ie9 +

Benjamin Crouzier
la source
2

Cela peut être déroutant, je suis d'accord. Essayez d'utiliser les fonctions de table. J'utilise cette astuce CSS simple pour positionner les modaux au centre de la page Web. Il prend en charge un grand navigateur:

<div class="table">
    <div class="cell">
        <img src="..." alt="..." />
        <span>It works now</span>
    </div>
</div>

et partie CSS:

.table { display: table; }
.cell { display: table-cell; vertical-align: middle; }

Notez que vous devez styliser et ajuster la taille du conteneur d'image et de table pour le faire fonctionner comme vous le souhaitez. Prendre plaisir.

CodeGems
la source
0

Tout d' abord CSS en ligne n'est pas recommandé du tout, il gâche vraiment votre code HTML.

Pour aligner l'image et la portée, vous pouvez simplement le faire vertical-align:middle.

.align-middle {
  vertical-align: middle;
}
<div>
  <img class="align-middle" src="https://i.stack.imgur.com/ymxaR.png">
  <span class="align-middle">I'm in the middle of the image! thanks to CSS! hooray!</span>
</div>

Alireza
la source
2
Il existe de nombreuses bonnes raisons d'utiliser le CSS en ligne. React: CSS en JS par exemple.
jlyonsmith
0

Je ne sais pas pourquoi il ne s'affiche pas sur le navigateur de votre navigation, mais j'utilise normalement un extrait comme celui-ci lorsque j'essaie d'afficher un en-tête avec une image et un texte centré, j'espère que cela aide!

https://output.jsbin.com/jeqorahupo

            <hgroup style="display:block; text-align:center;  vertical-align:middle;  margin:inherit auto; padding:inherit auto; max-height:inherit">

            <header style="background:url('http://lorempixel.com/30/30/') center center no-repeat; background-size:auto; display:inner-block; vertical-align:middle; position:relative; position:absolute; top:inherit; left:inherit; display: -webkit-box; display: -webkit-flex;display: -moz-box;display: -ms-flexbox;display: flex;-webkit-flex-align: center;-ms-flex-align: center;-webkit-align-items: center;align-items: center;">

            <image src="http://lorempixel.com/60/60/" title="Img title" style="opacity:0.35"></img>
                    http://lipsum.org</header>
                    </hgroup>
Jean Paul AKA el_vete
la source
0
<!DOCTYPE html>
<html>
<head>
<style>
 .block-system-branding-block {
 flex: 0 1 40%;
}
@media screen and (min-width: 48em) {
.block-system-branding-block {
flex: 0 1 420px;
margin: 2.5rem 0;
text-align: left;
}
}
.flex-containerrow {
display: flex;
}
.flex-containerrow > div {
  justify-content: center;
align-items: center;
  }
 .flex-containercolumn {
display: flex;
flex-direction: column;
}
.flex-containercolumn > div {
  width: 300px;
 margin: 10px;
 text-align: left;
 line-height: 20px;
 font-size: 16px;
}
.flex-containercolumn  > site-slogan {font-size: 12px;}
.flex-containercolumn > div > span{ font-size: 12px;}
</style>
</head>
<body>
<div id="block-umami-branding" class="block-system block- 
system-branding-block">
  <div class="flex-containerrow">
 <div>
  <a href="/" rel="home" class="site-logo">
  <img src="https://placehold.it/120x120" alt="Home">
</a>
</div><div class="flex-containerrow"><div class="flex-containercolumn">
  <div class="site-name ">
    <a href="/" title="Home" rel="home">This is my sitename</a>
   </div>
    <div class="site-slogan "><span>Department of Test | Ministry of Test | 
 TGoII</span></div>
 </div></div>
</div>
 </div>
</body>
</html>
Pradeep
la source
-4

Vous voulez probablement ceci:

<div>
   <img style="width:30px; height:30px;">
   <span style="vertical-align:50%; line-height:30px;">Didn't work.</span>
</div>

Comme d'autres l'ont suggéré, essayez vertical-alignl'image:

<div>
   <img style="width:30px; height:30px; vertical-align:middle;">
   <span>Didn't work.</span>
</div>

CSS n'est pas ennuyeux. Vous ne lisez simplement pas la documentation . ; P

strager
la source
6
Et si la hauteur de l'image est dynamique? Je suis foutu :( PS, juste parce que la documentation existe pour CSS ne le rend pas ennuyeux ou peu intuitif.
sam
Voulez-vous dire ennuyeux et intuitif? Vous n'avez pas précisé si la hauteur de l'image est dynamique dans votre question, j'ai donc supposé que la hauteur fixe était celle avec laquelle vous alliez vous en tenir.
strager
2
Je suis avec Sam sur celui-ci. J'ai supposé que les articles devaient être centrés avec quelle que soit la hauteur img. Je pense que nous pourrions tous nous reposer un peu.
Michael Haren