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.
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.
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’undisplay: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”
Laissez un commentaire
Chouette article. Tu vois un intérêt aux expressions css par rapport à un bête javascript ?
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 😉
@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.
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).
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 ! 😉
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.
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 !
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é.
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.