Mise en forme : passer des tableaux (table) aux blocs (div)

Cet article est inspiré d’une conversation sur WebRankInfo.

Introduction

Aujourd’hui, la conception des sites web se fait de plus en plus en respectant les recommandations de la W3C (il y a encore des irréductibles). Il est maintenant recommandé de séparer la mise en forme de la structure HTML. Pour cela, on externalise cette mise en forme dans des fichiers CSS.

Ce principe permet de rendre l’application plus flexible en permettant de modifier la mise en forme d’un site sans remanier le HTML. En outre, en configurant correctement le cache du navigateur, vous épargnez à vos visiteurs un chargement plus long. Grâce au cache, les fichiers CSS seront téléchargés une et seulement une seule fois. Résultat :

  • moins de requête
  • moins de bande passante utilisée (ça va vite).
  • économie de serveur : au lieu de rendre toujours le même fichier, il peut s’occuper d’autre chose.

Ce sont les gros points.

Maintenant, il reste un gros point noir. En effet, certain utilise encore les tableaux pour mettre en forme leur site web. Hors, cela va à l’encontre du rôle des tableaux, conçut pour afficher des données tabulaires (comme dans un tableur). C’était bien pratique il y a 10 ans (voir plus), mais maintenant, il est temps de revenir sur la bonne route.

Des tableaux vers les blocs de contenu.

La question que l’on doit se poser est : vais-je rencontrer des problèmes ? Eh bien la réponse est simple : oui.

Le comportement des navigateurs est parfois étrange dans certaines situations avec l’utilisation du CSS, et on ne comprend pas toujours pourquoi. Mais avec les bonnes pratiques sous le coude, on se rendra compte qu’il est simple de rendre compatible les sites avec la plupart des navigateurs. Pour moi, il est impossible de revenir à la mise en forme via les tableaux, ce serait une grosse perte de temps.

Je tiens à préciser qu’il est nullement question de bannir les tableaux des sites web. Dans certains cas, les tableaux ont toute leur utilité, notamment dans les parties administration. Si l’on prend exemple sur phpMyAdmin, les tableaux sont utilisés pour lister les données d’une table de base de données, c’est une utilisation normale des tableaux.

Exemple de maquette de site à 3 colonnes avec entête et pied de page.

Voici ce que nous souhaiterions avoir :

C’est donc un site centré sur la page contenant 3 colonnes. Je vais directement vous donner le code source xHTML ainsi que du CSS. Ce qui sera commenté par la suite.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="fr">
    <head>
        <!-- l'UTF-8, c'est bon. -->
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 
        <title>Test d'un site sur 3 colonnes</title>
        <link href="styles.css" media="all" rel="stylesheet" type="text/css" />
    </head>
    <body>
        <div id="container">
            <div id="header"></div>
            <div id="menu1"></div>
            <div id="content"></div>
            <div id="menu2"></div>
            <div id="footer"></div>
        </div>
    </body>
</html>

Dans le fichier « styles.css » :

#container {
    width: 900px;
    margin: 0 auto;
}
#header {
    margin-bottom: 20px;
}
#menu1, #menu2 {
    float: left;
    width: 128px;
    border: 1px solid #000;
    padding: 10px;
}
#content {
    border: 1px solid #000;
    margin: 0 10px;
    padding: 10px;
    width: 558px;
    float: left;
}
#footer {
    margin-top: 20px;
    clear: both;
}

div#container

C’est un bloc que je place systématiquement. Il me permet de définir la largeur principale du site, ici 900 pixels. Nous centrons le tout en définissant les marges droite et gauche à « auto ». Ceci n’est possible que si l’élément HTML possède une taille définie (peu importe sa valeur).

De cette manière, tous les blocs contenus dans ce conteneur auront la taille souhaitée (sans la préciser à chaque fois).

On aurait pu mettre directement ces styles sur la balise « body ». J’ai déjà testé, et cela fonctionne.

div#header

Un simple entête avec une marge basse de 20 pixels. J’aime bien définir mes informations le moins de fois possible. Au lieu de mettre une marge haute de 20 pixels aux menus et au contenu, je le met sur l’entête. Cela peut paraitre élémentaire, mais on a vite fait de faire compliqué quand on peut faire simple … Le changement de valeur est alors plus simple.

div#menu1 et div#menu2

Nous définissons les propriétés des menus. Comme je souhaite mettre les mêmes valeurs, j’ai utilisé « #menu1, #menu2 {} » pour appliquer les styles aux deux menus simultanément. Ceci évite la redondance d’information. J’aurai aussi pu utiliser une classe CSS sans problème.

Là ça va se compliquer (enfin, pas trop, pas de panique). Lorsque que vous définissez une largeur (ou hauteur) à un bloc, celle-ci ne prend en compte ni les marges intérieurs ni la taille des bordures. Par exemple, si vous définissez une largeur de 100 pixels avec une bordure de 2 pixels, vous vous retrouvez avec un bloc d’une largeur réel de 104 pixels.

Pour mon site, je souhaite que mes menus aient une largeur de 150 pixels, tout compris, pas un pixel de plus !!! Dans l’exemple, mes menus doivent avoir une bordure d’un pixel et une marge intérieur de 10 pixels. Là, il faut être une bête en soustraction.
Calcul : 150 (ma taille souhaitée) – 2 x 1 (j’ai 2 bordures d’1 pixel) – 2 x 10 (marges droite et gauche de 10) = 128 pixels.

La largeur à définir est donc de 128 pixels (propriété « width » pour ceux qui ne suivent pas 😉 ). Si vous avez compris ce principe de calcul de largeur et de hauteur, vous avez déjà 80% de l’expérience nécessaire à la conception de site web avec des blocs « DIV ».

div#content

Ici, je me pose la question suivante : « de combien je souhaite espacer mon contenu de mes menus ? ». Je pense que certains préfèreront définir une taille spécifique au contenu et ensuite une taille sur les menus en conséquence, mais moi, je ne fais pas comme tous le monde 😀

Dans cet exemple, l’espace est de 10 pixels. Nous reprenons donc notre calcul habituel. La largeur du conteneur étant de 900 pixels et mes menus occupant 300 pixels de largeur, il ne nous reste plus que 600 pixels à notre disposition.

Nous allons donc déduire la largeur à spécifier (toujours avec « width ») grâce au calcul suivant :
600 – 2 x 10 (marges gauche et droite de 10) – 2 x 10 (marges intérieurs gauche et droite de 10) – 2 x 1 (on n’oublie pas la bordure) = 558 pixels.

Nous définissons donc la largeur à 558 pixels, et pas un de plus ! Sinon vous allez rencontrer un comportement gênant que j’expliquerai plus bas.

div#footer

Même principe que l’entête, sauf que nous définissons une marge haute de 20 pixels. Une petite différence, on lui met la propriété « clear » à « both », vous verrez pourquoi un peu plus loin.

C’est terminé

Voila, votre structure HTML/CSS est prête à accueillir vos contenus. Avec un peu d’entrainement, on prend vite goût à ce nouveau mode de travail, et on se rend compte qu’on y gagne beaucoup.

Problèmes et solutions

Bien évidemment, et comme dans tout les cas, il y a des problèmes qui nous prend parfois la tête durant des heures. Mais heureusement, si le travail est bien fait dès le début, ce ne sera un problème que durant ce petit cours 😉

Voici le premier problème que vous pourriez rencontrer. Vous remarquez en effet que le menu droit passe en dessous du menu gauche. Cela se produit lorsque des éléments flottant sont placés à la suite et que la largeur totale excède celle du conteneur. Dans cette largeur totale, il faut prendre en compte les largeurs, les marges (intérieur et extérieur, soit padding et margin) et enfin les bordures de chaque élément.

C’est pour cela qu’il est impératif de calculer correctement les largeurs des blocs, sinon on se retrouve avec ce comportement.

 

Second problème : on voit ici que le conteneur ne prend pas la hauteur qu’il devrait avoir. En effet, lorsque ses fils sont flottant, ces derniers quittent le flux normal d’affichage. C’est un peu le même comportement avec la position absolue. Pour forcer le conteneur à retrouver sa hauteur, il existe plusieurs méthodes dont l’utilisation de « clear ». C’est la méthode que j’utilise. Pour forcer la conteneur à prendre un bonne hauteur, il suffit de mettre la propriété « clear » à « both » sur le bloc de pied de page (#footer).

Parfois, il n’y a pas de bloc à notre disposition pour cette tâche. Il suffit dans ce cas de mettre un élément invisible. Personnellement, je procède par l’ajout d’un élément « span » avec un style CSS, comme suit :

<span class="clear">&nbsp;</span>

À placer à la fin du conteneur.
Le style CSS à appliquer :

span.clear {
    font-size: 1px;
    display: block;
    clear: both;
    visibility: hidden;
}

En théorie, ce seront les deux plus gros problèmes que vous pourriez avoir, mais avec un peu de rigueur et une bonne réflexion ce sera surmonter sans souci.

Conclusion

Ici, je vous ai expliqué ma façon de faire, mais si vous trouvez mieux, n’hésitez pas à faire autrement. Le but est de donner un point de départ au nouveau arrivant dans la mise en forme sans tableau. Vous vous ferez votre propre expérience et ferez peut-être mieux que moi. Avec HTML5, la donne va changer, et je pense que cet article sera vite périmé 😉

Si vous avez des commentaires, n’hésitez pas.

5 réflexions sur « Mise en forme : passer des tableaux (table) aux blocs (div) »

  1. Bon article merci. 🙂
    La transition est dure au début mais ça vaut vraiment le coups de passer à une mise en forme correcte, c’est beaucoup plus clair.

    Sinon par rapport à ta conclusion, HTML5 ne change pas grand chose dans ce domaine il me semble, avec CSS3 ils ajoutent de nombreuses nouveautés mais rien de spécial au niveau du positionnement.

  2. Merci pour l’article.

    Comment se fait-il que la disposition n’est pas maintenue lorsque l’on réduit le facteur zoom des navigateurs ?

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Notifiez-moi des commentaires à venir via email. Vous pouvez aussi vous abonner sans commenter.