Niveau : Confirmé

Comment centrer verticalement sur tous les navigateurs ?

Tutoriel par (Intégrateur web, Lyon)
Mis à jour le . 176983 lectures.
Tags : css, centrer, centrage, vertical

Ce tutoriel présente des solutions pour centrer verticalement des éléments de tailles variables dans des conteneurs de hauteur fixe ou fluide. Les techniques exposées sont compatibles avec tous les navigateurs actuels, à partir d'Internet Explorer 7 (IE6 n'est volontairement pas abordé) et n'utilisent ni <table>, ni JavaScript.

Sommaire

  1. Introduction
  2. Avant d'aller plus loin
  3. Centrage vertical dans un conteneur de hauteur fixe avec :
  4. Centrage vertical dans un conteneur de hauteur fluide avec :
  5. Conclusion

Introduction

Le temps du valign=middle sur nos tableaux de mise en page est bel et bien révolu. La démocratisation de la sémantique (X)HTML a donné naissance à de jolis gabarits standardisés, mais a également marqué la disparition des techniques simples pour centrer verticalement.

Avec CSS2 et l'arrivée de nouvelles valeurs pour la propriété display, beaucoup ont vu en table-cell une nouvelle ère pour le centrage vertical. Cette valeur permet d'indiquer qu'un élément doit se comporter comme une cellule d'un tableau, sur laquelle le vertical-align:middle pourrait fonctionner. Comme à la bonne époque des <table>. Malheureusement, c'était sans compter sur le vilain petit canard : Internet Explorer. En effet, celui-ci ne supporte display:table-cell qu'à partir de sa version 8 et +.

Bref, le dossier "display:table-cell et centrage vertical" fût rangé au placard, on s'est dit qu'on le ressortirait après les funérailles d'IE6 et d'IE7. L'acharnement provoqué autour de la propriété table-cell a finalement réussi à ancrer dans les mœurs des idées bien reçues autour du centrage vertical : Non, il n'est pas possible aujourd'hui de centrer verticalement à cause d'IE.

Pourtant, si l'on remonte à la source et que l'on regarde la spécification de la propriété vertical-align :

La propriété vertical-align s'applique aux éléments de type en-ligne et à l'élément table-cell.

On retrouve effectivement notre ami table-cell, mais pourquoi la piste des éléments "en-ligne" a t-elle suscité aussi peu d'attention ?

Et au fait, le vertical-align ça marche comment ? Descendons un peu plus bas dans la doc :

vertical-align se rapporte à la valeur de la propriété line-height de l'élément lui-même.

Donc pour résumer, et sans rien inventer, le centrage vertical doit théoriquement fonctionner sur un élément "en-ligne" (de nature, ou modifié avec display:inline-block), couplé avec un line-height adéquat. Essayons de voir ce que cela donne en pratique...

Avant d'aller plus loin

Attention Certaines solutions exposées dans ce tuto ne fonctionnent pas avec un doctype Transitionnel. En effet, ce dernier déclenche le mode "presque standard" qui provoque des comportements bizarres avec les images. Si possible, utilisez donc une DTD Strict.

  • Ce tutoriel n'a pas pour vocation d'expliquer en détail le fonctionnement du display:inline-block. Si vous n'êtes pas familier avec cette propriété je vous invite à consulter les ressources suivantes avant de continuer la lecture :

    Mise en page CSS avancée grâce à la propriété display (Alsacreations)
    Inline-block dans tous les navigateurs modernes ? (Covertprestige)

  • Ce tutoriel traite exclusivement du centrage vertical. Si vous souhaitez en savoir plus sur le centrage horizontal, jetez un coup d'oeil à cet article.

  • Le code présenté sur cette page a été allégé afin de ne présenter que l'essentiel de chaque technique. Vous trouverez le code complet dans les démos.

  • La plupart des techniques présentées ici utilisent du line-height sur des éléments (de nature ou modifiés) inline. Ce qui veut dire que le résultat peut varier en fonction de la police utilisée et de sa taille (donc du navigateur, du système d'exploitation, etc.). D'une manière générale, n'utilisez pas ces techniques pour créer des gabarits où les éléments sont alignés au "pixel près", mais plus pour réaliser les mises en forme de vos contenus.

Centrer verticalement une image de taille variable dans un conteneur de hauteur fixe

Image centrée verticalement dans un conteneur de hauteur fixe

Écritures XHTML qui fonctionnent sur tous les navigateurs :

<p> <img src="img.jpg" alt=""/> </p>
<p><span><img src="img.jpg" alt=""/></span></p>
<p>
  <img src="img.jpg" alt=""/>
</p>

Ne fonctionne pas sur IE7 :

<p><img src="img.jpg" alt=""/></p>

Le code CSS :

p { 
  height:200px;
  line-height:200px;
  text-align:center; /* centrage horizontal d'un élément en-ligne */ }
img { 
  vertical-align:middle;
}

Attention Voir la démo

Concernant IE7, celui-ci a besoin d'espaces ou d'un élément "en-ligne" comme <span> autour de l'image pour déclencher le centrage. Pour entretenir sa réputation de maillon faible, sans doute.

Centrer verticalement une ligne de texte dans un conteneur de hauteur fixe

Ligne de texte centrée verticalement dans un conteneur de hauteur fixe

<p>Lorem ipsum</p>
p {
  height:200px;
  line-height:200px;
  text-align:center; /* centrage horizontal */
}

Attention Voir la démo.

Technique mondialement connue qui a fait ses preuves. On utilise le combo height / line-height pour réaliser le centrage, la propriété vertical-align devient optionnelle.

Centrer verticalement plusieurs lignes de texte dans un conteneur de hauteur fixe

Plusieurs lignes de texte centrées verticalement dans un conteneur de hauteur fixe

<p> <span>Lorem ipsum <br/> Cras [...]</span> </p>
p {
  height:200px;
  line-height:200px;
  text-align:center; /* centrage horizontal */
}

span { 
  width:100px; /* largeur zone de texte */
  border:1px solid #fff;
  vertical-align:middle;
  display:inline-block;
  line-height:1.2; /* on rétablit le line-height */
  text-align:left; /* ... et l'alignement du texte */
}

Attention Voir la démo.

Comme pour le centrage vertical d'une image, on dispose de 3 écritures pour faire fonctionner la technique sur IE7 (mettre des espaces, encapsuler dans un élément "en-ligne" ou encore indenter l'imbrication).

Pas besoin de corriger le inline-block pour IE7, cette valeur fonctionne correctement sur les éléments nativement "en-ligne".

Centrer verticalement un bloc dans un conteneur de hauteur fixe

Bloc centré verticalement dans un conteneur de hauteur fixe

<div class="conteneur">
  <div class="bloc">
    <h3>Kikoo !</h3>

    <p>Lorem ipsum [...]</p>
  </div>	
  <span></span>
</div>
div.conteneur {
  height:200px;
  line-height:200px;
  text-align:center; /* centrage horizontal */
}

div.bloc {
  width:100px;
  border:1px solid #fff;
  vertical-align:middle;
  display:inline-block;
  line-height:1.2; /* on rétablit le line-height */
  text-align:left; /* ... et l'alignement du texte */
}

Et pour IE7 seulement, à l'aide des commentaires conditionnels (ou d'autres choses) :

div.bloc { 
  display:inline; /* correctif inline-block */
}

div.conteneur > span { 
  zoom:1; /* layout */
}

Attention Voir la démo

La technique utilisée ici est très similaire à la précédente. Seul le correctif pour IE7 est un peu plus élaboré.

Sur IE7, le centrage vertical ne pose pas de problème avec des blocs alignés dans un conteneur de hauteur fluide (voir la méthode suivante du tutoriel). D'où l'idée d'utiliser un <span> de pleine hauteur mais de largeur nulle pour déclencher le line-height (un <span> doté du layout occupera toute la hauteur de son parent. La propriété display:inline-block permettant également de conférer le layout à un élément, on pourrait aussi l'utiliser à la place de zoom:1).

Et enfin, vous aurez remarqué le choix d'un sélecteur d'enfant ( > ) pour cibler le <span>, ce qui nous évite d'alourdir inutilement le code (X)HTML avec une classe CSS supplémentaire.

Centrer verticalement des blocs dans un conteneur de hauteur fluide

Blocs centrés verticalement dans un conteneur de hauteur fluide

<div class="conteneur">

  <div class="bloc">
    <p>Cras mollis [...]</p>
  </div>
	
  <div class="bloc">
    <p>Lorem ipsum [...]</p>
  </div>
	
</div>
div.conteneur { 
  text-align:center; /* centrage horizontal */
}

div.bloc { 
  width:100px;
  margin:0 10px; /* espacement horizontal des blocs */
  border:1px solid #fff;
  display:inline-block;
  vertical-align:middle;
  text-align:left; /* on rétablit l'alignement du texte */
}

Et pour IE7 :

div.bloc { 
  display:inline; /* correctif inline-block */
}

Attention Voir la démo

Rien d'extraordinaire dans cette technique, on applique simplement les bases du display:inline-block, sans oublier le correctif pour IE7 qui ne reconnait inline-block que pour les éléments naturellement "en-ligne".

Notez toutefois que pour fonctionner sur IE7, le bloc doit également avoir le layout (qui est conféré automatiquement si celui-ci a une largeur fixe en pixel ou en pourcentage. Si ce n'est pas le cas, et en dernier recours, on pourra ajouter un zoom:1 ou un height:1% au correctif).

Conclusion

Les méthodes exposées dans ce tutoriel devraient vous permettre de coder vous-même les quelques cas de figure manquants (notamment en ce qui concerne les conteneurs de hauteur fluide).

N'oubliez pas que les résultats obtenus dépendent fortement du contexte dans lequel sont placés les éléments. Et que ceux-ci peuvent être décalés de quelques pixels (par rapport à un centrage parfait) en fonction de la police et de sa taille. Le décalage reste tout de même quasiment invisible à l'oeil nu. Vous pouvez donc utiliser sans crainte ces solutions en production.