CSS: vertical-align:middle pour Internet Explorer 6 et 7

Depuis la fin des mises en pages en tableaux html, centrage vertical d'un élément dans son conteneur a toujours posé des problèmes.

Internet Explorer et le vertical-align

En cause, Internet Explorer dans les versions 6 et 7 (je ne parle même pas des versions antécédantes) ne supportent pas correctement la propriété CSS display:table-cell.

En effet, le seul moyen correct de centrer verticalement un élément est de faire en sorte que l'élément parent se comporte comme une cellule de tableau (d'où des réactions folkloriques).

Le display:table-cell a été introduit dans Internet Explorer 8. Avant ça, toutes les solutions avaient leurs revers : line-height qui ne permet pas d'avoir des espacements de lignes correct, hauteur des éléments impérativement fixe, hacks CSS mystérieux (dont on ne connaîtra pas le comportement dans les futurs navigateurs).

Bref, rien qui ne me satisfait pleinement.

CSS vertical-align:middle;

Dans Firefox 2 (pc), Firefox 3 (pc/mac), Chrome 1.0.154, Safari (4 pc, 3.2.1 mac), Opera 9.64 (pc/mac), Camino, Shira, IE8, le code suivant est bien rendu.

texte centré verticalement correctement avec vertical-align:middle dans les browsers CSS

Le code HTML

<div class="v">
	<div>Ce texte devrait être centré verticalement</div>
</div>

Le code CSS

<style type="text/css">
.v {
	display:table-cell;
	vertical-align:middle;
	/*les 3 lignes suivantes ne sont pas nécessaires*/
	background:#900;
	height:250px;
	width:150px;
}
.v div {
	/*non nécessaire, juste de la décoration pour mieux visualiser*/
	background:#090;
}
</style>

Par contre dans IE 6 et 7, l'alignement vertical n'est pas pris en compte et la boîte de texte reste en haut de la boîte bleue.

texte centré verticalement incorrectement dans IE6

Expressions CSS à la rescousse

Encore une fois, les expressions CSS d'Internet Explorer – qui, je sais, ne sont pas recommandées pour des raisons de performances et qui ont été supprimées d'IE8 – peuvent nous être bien utiles.

Code

<!--[if lt IE 8]>
<style type="text/css">
.v {
	position:relative;
	width:expression(this.childNodes[0].offsetWidth+"px");
}
.v div {
	position:absolute;
	top:50%;
	margin-top:expression(-this.offsetHeight/2);
}
</style>
<![endif]-->

Le contenu sera positionné en absolu, à cinquante pourcent du top, par rapport à son conteneur. Il aura aussi une marge négative de la moitié de sa hauteur.

Comme, le contenu est placé en absolu, il sort du flux de la page. Sa largeur est donc reportée sur le conteneur.

Remarques et limitations :

  • voir la démo
  • Les commentaires conditionnels sont employés pour cibler les version d'Internet Explorer inférieures à 8.
  • Les expressions css ne sont pas exécutées si le navigateur à le JavaScript désactivé.
  • Les impacts de preformance sont à tenir en compte : les expressions CSS sont recalculées à chaque changement de propriétés CSS dans la page (redimensionnement du navigateur etc,...)
  • Le comportement d'un élément en display:table-cell est différent de celui d'un display:block. S'il doit prendre la largeur d'un conteneur, il faudra spécifier celle-ci.

Comments

9 commentaires à “CSS: vertical-align:middle pour Internet Explorer 6 et 7”

  1. Ced le 26/04/2009 à 18h43.

    Chouette article. Tu vois un intérêt aux expressions css par rapport à un bête javascript ?

  2. Palleas le 27/04/2009 à 07h20.

    Je crois que c'est une technique à éviter si on ne veut pas que l'extension YSlow nous fasse la tête, même si ça reste très pratique ;)

  3. Marin le 27/04/2009 à 08h44.

    @Ced: par rapport à une solution purement JS, l'avantage est de ne pas avoir des boucles sur tous les éléments portant une certaine classe, les css expressions s'en occupent pour toi. (Et donc pour les feignasses, ne pas devoir prendre une librairie JS type jQuery avec lequel on devrait faire: $(".v div").each(function(){/*this.blabla*/});

    @Palleas: je suis conscient de l'impact des expressions css sur les performances web. Dans ces cas-ci, je demanderai à mon designer de revoir son layout pour éviter un alignement vertical. Ou alors, encore mieux, je lui demanderai de proposer un layout alternatif pour les navigateurs obsolètes. Ces expressions css sont à employer précautionneusement et en connaissance de cause bien évidemment.

  4. Vincent le 18/07/2009 à 15h16.

    Un autre problème persiste tout de même avec display: table-cell. Ca ne semble pas fonctionner si la hauteur n'est pas fixée en pixel (par exemple avec width: 100%; ca ne fonctionne pas).

  5. Alexandre le 14/10/2009 à 00h24.

    Un commentaire un peu Hors-Sujet mais je voulais te remercier pour ton blog qui m'a donné un gros coup de main pour la modification d'un thème WordPress, voila c'est tout ! ;)

  6. Sybille le 07/11/2009 à 01h40.

    Alors ça c'est exactement le problème de centrage vertical que j'ai rencontrée il n'y pas si longtemps sur mon site.
    Thanks pour l'info.

  7. Nova le 21/05/2011 à 17h01.

    J'aime bien cette article, ça me donne des idées.
    Il me semble que j'avais déjà essayé de faire ça sans y parvenir.
    Merci !

  8. data-j@ck le 26/11/2011 à 21h37.

    Sinon, il y a une méthode plus simple pour un vertical-align avec IE7 :

    Réduire la largeur de l'élément à aligner verticalement d'une dizaine de pixels, par rapport à son conteneur.

    J'ai eu le cas pour un diaporama récalcitrant. Et cette onction m'a bien aidé.

  9. data-j@ck le 26/11/2011 à 21h44.

    IE7 vertical-align, détails :

    #conteneur { width: 790px; margin: auto 0; }
    .contenu { width: 785px; }

    J'ai pas testé toutes les possibilités. Mais c'est une piste à suivre.

Laissez un commentaire