: css

Le centrage vertical

Le centrage vertical d'un block est l'une des grosse problématique en css ces dernières années. Il n'existait pas de solution vraiment efficace, tous navigateurs. Aujourd'hui faire appel à diverses techniques sur les navigateurs un minimum récents (IE8 +).

Nous allons passer en revue ici différentes options pour aborder le centrage vertical

Le display:table et table-cell

A l'intérieur d'un tableau, il est possible de centrer les éléments verticalement à l'aide la propriété vrertical-align. L'idée est donc de jouer avec un display:table et display:table-cell afin de pouvoir utiliser le vertical-align:

<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8" />
<title>Centrage vertical</title>
<style type="text/css">

        html,body {
                width:100%;
                height:100%;
                margin:0;padding:0;
        }


        html {
                display:table;
        }

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


        div {
                width:600px;
                height:400px;
                background:red;
                margin:0 auto;
                border:1px solid black;
        }



</style>
</head>
<body>
<div>élément à centrer</div>
</body>
</html>

Explications:

Cette solution fonctionne correctement et efficacement sur tous les navigateurs prenant en compte le display:table. Sur les anciennes versions d'IE (7-) le centrage horizontal étant quand même effectif, on peut pallier au vertical en rajoutant un petit peu de JS par le biais d'un commentaire conditionnel:

<!--[if lt IE 8]>

  <style type="text/css">
                div {
                        position:relative;
                        top:expression(document.body.clientHeight<=this.offsetHeight ? "0" : (document.body.clientHeight-this.offsetHeight)/2+"px");
                }
        </style>

<![endif]-->

Le gros avantage de cette solution est de permettre une hauteur de l'élément flexible. Il est clair que, pour l'exemple, on a attribué un height, mais on pourrait très bien centrer verticalement un élément avec un height auto et quivs'adapte donc au contenu.

Le positionnement absolu

A l'aide des marges négatives

L'idée est de décaler l'élément à centrer des 50% de la hauteur de la fenêtre, puis de le positionner correctement à l'aide d'un margin négatif de la moitié de ses dimensions:

 div {
    width:600px;
    height:400px;
    background:red;
    border:1px solid black;
    position:absolute;
    top:50%;left:50%;
    margin-top:-201px;
    margin-left:-301px;
  }

Cette solution à l'avantage de fonctionner sur tous les vieux navigateurs mais elle a 2 inconvénients majeurs:

Si, connaitre la hauteur de l'élément est incontournable, on peut, par contre, essayer de maitriser la problématique du contenu qui disparait.

position:relative au lieu de absolute

En utilisant un position:relative on règle déjà la problématique de la disparition du contenu sur la gauche puisque l'on peut utiliser les marges latérales à auto pour centrer notre élément. De même, connaître la largeur de l'élément n'est alors plus une contrainte:

 html,body {
    margin:0;padding:0;
    height:100%;
  }

  div {
    width:600px;
    height:400px;
    background:red;
    margin:0 auto;
    border:1px solid black;
    position:relative;
    top:50%;
    margin-top:-201px;
  }

Remarque:

Puisqu'on utilise un positionnement relatif, on est maintenant obligé de spécifier une hauteur de 100% au body et à l'html. Avec le positionnement absolu, c'était inutile puisque, par défaut, c'est la hauteur de la fenêtre qui sert de référence.

un min-height sur le body

Pour éviter que le contenu du haut ne disparaisse on peut ajouter un min-height de la hauteur de l'élément à centrer sur le body:

 body {min-height:402px;}

On pourra compléter par du javascript pour IE6 qui ne sait pas interpréter min-height:

<!--[if lt IE 7]>

  <style type="text/css">
                div {
                        margin-top:0;
                        top:0;
                        top:expression(document.body.clientHeight<=this.offsetHeight ? "0" :  (document.body.clientHeight-this.offsetHeight)/2+"px");
                }
  </style>

<![endif]-->

En remettant le margin-top ainsi que le top à 0, on s'assure, au ca ou javascript serait désactivé, que le contenu sera toujours accessible; il ne sera simplement pas centré verticalement.

A l'aide de margin:auto

Cette technique, qui fonctionne depuis IE8 est assez peu utilisée parce qu'assez méconnue. Lorsque les propriétés top, bottom, right et left sont toutes indiquées à 0 et que l'élément possède un width, alors l'élément positionné en absolute va se centrer à l'aide des marges auto.

Cela est particulièrement intéressant pour centrer une image sans en connaître les dimensions:

<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8" />
<title>Centrage vertical</title>
<style type="text/css">

        html,body {
                height:100%;
                margin:0;padding:0;
        }


        body {
                position:relative;
        }


        img {
                position:absolute;
                top:0;bottom:0;left:0;right:0;
                margin:auto;
        }



</style>
</head>
<body>
<img src="monimage.jpg">
</body>
</html>

A l'aide d'un tableau

Cette solution peut s'avérer utile en cas de support sur de tout vieux navigateurs sans vouloir se prendre la tête. Mais rappelons-le, les tableaux doivent présenter des données tabulaires et non servir pour de la mise en page. Le code html deviendrait:

<body>
  <table>
    <tr>
      <td>
        <div></div>
      </td>
    </tr>
  </table>
</body>

Avec comme css:


        html,body,table,tr,td {
          width:100%;
          height:100%;
          margin:0;padding:0;
        }

        td {
          vertical-align:center;
        }

        div {
          width:600px;
          height:400px;
          background:red;
          margin:0 auto;
          border:1px solid black;
        }
Editer