Comment centrer un texte, une figure, ou toute une page avec des feuilles de style ?

En préliminaire, précisons que nous ne parlerons pas du cas désespéré de NN4. Nous aurons déjà assez à faire avec les comportements parfois divergents de IE5.5, IE5-mac et IE6... On peut toutefois assez facilement s'arranger pour que ça fonctionne à peu près partout.
  1. Le principe du margin:auto
  2. Le décalage de 50% avec marges négatives
  3. Le text-align:center n'est pas une solution...
  4. ...mais il a des applications
  5. Recentrage d'une page en calques déjà faite
  6. Centrage vertical

1 —Le principe du margin:auto

On n'a rien prévu d'aussi simple que la balise <center> du HTML classique. La méthode préconisée est de mettre
margin-left: auto; margin-right: auto; 
ou, plus simplement, margin:auto dans le style de l'objet à centrer.
Démonstration : ce texte sur fond bleu est écrit dans un <DIV> de largeur 400 ainsi autocentré (en principe) tandis que l'image ci-dessous est dans un autre bloc <DIV> de même largeur que l'image, également autocentré — en principe. Le centrage se fait ici par rapport au <BODY>, c.à.d. le fond de la page.
image de test

Sur MacOS, ça fonctionne bien avec IE5, et les navigateurs conformes (Mozilla, NN6 et Opera6...) mais, une fois de plus, pas avec NN4...

Sur Windows, ça fonctionne avec les navigateurs conformes (Mozilla, NN7, Opera7), mais pas avec IE5.5. Avec IE6, il faut avoir pris la précaution de passer en mode conforme W3C, par exemple en ayant placé en tête de page l'un des doctypes suivants:
   <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
          "http://www.w3.org/TR/html4/loose.dtd">
   <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
(l'URL dans le doctype est obligatoire en HTML Transitional ; on peut remplacer HTML 4.0 par HTML 4.01).
A noter que IE5-mac passera lui aussi en mode conforme (sauf avec <!DOCTYPE HTML PUBLIC "-//W3C//DTD <B>HTML 4.01</B>//EN">, sans URL) avec en cadeau l'apparition fâcheuse, de temps en temps, de bugs de rendu. Il n'y a malheureusement pas grand chose à faire si on ne peut pas utiliser ce doctype particulier, sinon pousser les gens sur MacOS à passer sur Mozilla... :-)

2 — Une autre technique : décalage de 50% et marge négative

Si l'objet à centrer a une largeur bien définie, on peut le centrer avec les propriétés de style suivantes :
        width:largeur ; 
        position:relative; left:50% ; margin-left:-demi_largeur 
largeur est la largeur de l'objet (en px, em, etc...) et demi_largeur sa moitié.

Explication : la propriété position:relative; permet de déplacer l'objet par rapport à sa position naturelle ; le left:50% le déplace vers la droite de la moitié du bloc père (ici, le BODY), et le margin-left négatif ajoute le déplacement voulu vers la gauche.

A titre d'exemple, ce bloc bleu-vert de largeur 28em est centré par position:relative; left:50% ; margin-left:-14em tandis que l'image ci-dessous, de largeur 55px, est centrée, dans ce bloc même, par le style position:relative; left:50% ; margin-left:-27px appliqué directement à la balise image
image de test
(Il faut évidemment mettre un <br> avant l'image, afin que sa position initiale naturelle soit à gauche du bloc)

Sur Windows, cette technique a le mérite de fonctionner sur IE5.5, mais aussi sur IE6 (que l'on soit en mode conforme ou pas) et sur les navigateurs conformes.
Sur Mac OS, elle fonctionne sur IE5 et les navigateurs conformes.

3 — Le text-align:center **N'EST PAS** une solution !

Sous Windows avec IE5.5 ou IE6 ou sous MacOS avec IE5 (ces deux derniers en mode non-conforme, par exemple sans doctype en tête de page), text-align:center dans un bloc <DIV> a la vertu de tout centrer dans ce bloc, que ce soit un simple texte (c'est bien le moins, puisque c'est fait pour ça :-)), mais aussi les autres blocs <DIV> ou les figures. Mais c'est une fausse solution, qui ne fonctionne qu'avec les Explorer

Notamment, cela ne fonctionne pas avec Opera-7 dans son mode quirks «quasi-microsoft».

A titre d'exemple, nous avons repris les blocs précédents, nous leur avons enlevé leur autocentrage, et nous avons remis le tout dans un bloc <DIV> de largeur 100% avec un text-align:center (et nous avons pris soin de placer en tête de cette page un doctype qui laisse IE5-mac et IE6 dans leur mode «microsoft») :

Le pavé bleu ou l'image se centrent avec Explorer... mais avec aucun des autres navigateurs !
image de test

Si on met l'un des DOCTYPE cités plus haut en tête de page, ce centrage disparaît avec IE5-mac, IE6-win ou Opera-7 (mais il reste avec IE5.5-win).

4 — Mais ce text-align:center peut tout de même être utile !

D'abord à des fins de compatibilité : si on centre avec margin:auto et si on met ce text-align:center dans le style du bloc père, on aura le centrage aussi bien avec les navigateurs conformes (par le margin:auto) que pour les navigateurs «microsoft» (par ce text-align:center). Evidemment, il faudra éventuellement reprendre les text-align de tous les blocs fils.

Ensuite (pour le fun), en fait, on peut bel et bien centrer à peu près tout avec ce text-align:center : il suffit de transformer les éléments à centrer en autant de lignes de texte ! L'illustration ci-dessous en donne la démonstration. Pour les images, il suffit de mettre les <IMG> les uns à la suite des autres et de placer des caractère invisibles   devant et derrière, car les images se placent naturellement dans un flux naturel en ligne. Pour les boîtes du type bloc (DIV ou TABLE), on forcera ce comportement avec un style display:inline.
Notez qu'on aurait le même effet en plaçant tous ces éléments dans des paragraphes avec le même text-align:center.

 image de test image de test image de test 
 
Boîte DIV avec display:inline
 

5 — Pour centrer une page ou recentrer une page déjà faite...

Il s'agit d'un problème que l'on rencontre assez souvent quand on construit ses pages avec des logiciels wyziwyg. La plupart du temps, ceux-ci mettent en place des blocs <DIV> positionnés en absolu depuis le coin en haut à gauche, et la page reste ainsi collée à la gauche de l'écran. Pour recentrer l'affichage, il devrait suffire d'enserrer tout le code dans un bloc <DIV> autocentré avec un width correspondant à la largeur de l'affichage (sans ce width, le bloc prendrait toute la largeur de la fenêtre et l'auto-centrage n'aurait pas d'effet). Bien sûr, ça ne marchera pas avec NN4, mais sans autre catastrophe que de faire perdre le centrage... Le code sera
<BODY>
<div style="position:relative; width:700px; 
 margin-left: auto; margin-right: auto; ">
    ... [code de la page] ...
</div> 
Vous devrez bien entendu adapter le width à votre cas particulier. Attention, le position:relative est fondamental, sinon le bloc ne pourrait pas servir de référence aux différents éléments qu'il contient ; la norme du W3C exige pour un bloc de référence d'avoir un style position déclaré, soit absolute, soit relative.

Démonstration : cliquez ici.

Si ça ne fonctionne pas chez vous, l'affichage doit rester collé sur la gauche, comme auparavant, sans plus de dommage. Ça fonctionnera peut-être avec la version suivante de votre navigateur... :-))

Il faut bien sûr mettre l'un des DOCTYPES ci-dessus pour que l'affichage se centre avec IE6-win.

En principe et en bonne logique W3C, on devrait pouvoir transférer le style précédent directement dans le BODY et faire l'économie du DIV intermédiaire :
   <body style="position:relative; width:700px; 
    margin-left: auto; margin-right: auto; ">
    .... code de la page...
   </body> 
mais ça ne marche plus sur IE5-mac (plus de 90% des utilisateurs de Mac)... Par contre, NN6 (mac ou win), IE6 (en mode W3C), Konqueror ou Mozilla (unix) réagissent correctement. Testez ici votre navigateur sur ce point.

 

6 — Et pour centrer en hauteur ?

Quand on présente une page très courte, il est agréable de pouvoir la centrer en hauteur aussi bien qu'en largeur.

Emportés par une logique naturelle, on aurait pu penser que margin-top:auto; margin-bottom:auto; aurait permis d'obtenir le centrage vertical d'un objet d'un objet contenu dans un bloc plus grand et de hauteur spécifiée. Hélas, ça ne marche pas comme ça.

La technique du décalage de 50% et de la marge négative donnera généralement satisfaction. Le style à appliquer est similaire au style pour le centrage horizontal (et bien entendu, on pourra appliquer les deux simultanément) :
        height:hauteur ; 
        position:relative; top:50% ; margin-top:-demi_hauteur 
hauteur est la hauteur de l'objet (en px, em, etc...) et demi_hauteur sa moitié. Selon les cas, il faudra peut-être remplacer position:relative par position:absolute.

Démonstration : cliquez ici.
Ce principe fonctionne presque partout... mais pas partout : avec Konqueror 3.1 (linux) ou IE5-mac en mode conforme, tout est déplacé vers le haut et à moitié hors de l'écran, comme si on avait mis top:0%.

Même s'il s'agit de navigateurs très minoritaires, cet échec partiel est ennuyeux car on utilisera généralement ce centrage pour des pages d'introduction, sur lesquelles il importe de ne pas perdre bêtement de visiteur. On peut cependant pallier ces difficultés,
— pour Konqueror, en appliquant le style de centrage en deux étapes, comme expliqué ci-dessous;
— pour IE5-mac, en le laissant dans son mode non-conforme, en utilisant soit un doctype DTD HTML 4.01//EN, soit un doctype HTML-4 Transitional (mais les deux sans URL), soit encore en ne mettant pas de doctype du tout.

  1. Le bug de Konqueror se pallie en scindant le style de centrage en deux. On crée d'abord un bloc DIV centré, de dimensions arbitraires :
    <div id="relais" style="position:absolute; top:50%; left:50% 
    width:20px; height:20px; overflow:visible;">
    et on se sert de ce bloc relais pour positionner le bloc général qui va servir de référence aux différents calques composant la page:
    <div id="reference" 
    style="position:absolute; top:-demi_hauteur; left:-demi_largeur
    width:largeur; height:hauteur; ...">
    Comme on débordera du DIV «relais», le overflow:visible assurera que rien ne sera tronqué. On peut supprimer les ID «relais» et «reference», mais cela va simplifier les explications plus bas.
  2. Pour IE5-mac, il s'agit d'un bug plus profond de son mode conforme. Il ne sait pas sur quoi faire porter les 50% en hauteur. Il applique donc un décalage nul et on ne voit plus que le bas du bloc. Il retrouve de la mémoire si on ajoute un style html,body{height:100%}, mais, deuxième bug, il prend les 100% sur la hauteur physique de l'écran et non pas sur la hauteur de la fenêtre ouverte. La seule solution est de laisser IE5-mac en mode non-conforme (c.à.d. pas de doctype, ou un doctype Transitional sans URL, ou encore <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">, qui laisse IE5-mac en mode non-conforme et qui met IE6 en mode conforme)
  3. Mais un bug nouveau apparaît alors sur NN6-mac (qui marchait bien jusque là :-)) ! Il faut apparemment répéter la couleur de fond du BODY dans le «reference» (mettre inherit ou transparent ne sert à rien), à moins qu'il n'y ait une image de fond dans le BODY...

Ces trois modifications sont incluses dans notre démonstration finale (examinez son code et ses commentaires). Elle fonctionne dans tous les navigateurs... que nous avons essayés.

Charles — (TOM) — Gérald
... et Jim Davies, pour le chat Garfield