I. Introduction

Il n'est pas rare que l'on souhaite avoir un site structuré en trois colonnes, une à gauche pour le menu, une au centre pour le contenu et une dernière à droite pour le contenu associé à l'article. Bien souvent, l'utilisation des tableaux HTML est retenue car son implémentation est rapide et simple, mais erronée sémantiquement parlant. Nous allons donc voir comment simuler des cellules de tableau avec des <div> pour reproduire ce comportement en CSS.

Cette propriété est bien entendu disponible sur tous les navigateurs… Tous ? Hé non ! Il existe quelque part, outre-Atlantique, un navigateur qui résiste encore et toujours à l'envahisseur W3C ! (Je pense que tout le monde aura compris de qui l'on parle ici).

II. Le HTML

Voici donc l'ossature de la page sur le principe des colonnes factices.

index.html
Sélectionnez
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
  2. <html xmlns="http://www.w3.org/1999/xhtml"> 
  3. <head> 
  4.  <title>Colonnes factices en CSS</title> 
  5.  <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" /> 
  6.  <meta name="robots" content="none" /> 
  7.  <link rel="stylesheet" href="style.css" type="text/css" /> 
  8.  <!--[if lte IE 7]> 
  9.  <link rel="stylesheet" href="style_ie7.css" type="text/css" /> 
  10.  <![endif]--> 
  11.  <!--[if lte IE 6]> 
  12.  <link rel="stylesheet" href="style_ie6.css" type="text/css" /> 
  13.  <![endif]--> 
  14. </head> 
  15. <body> 
  16. <div id="header"></div> 
  17. <div id="container"> 
  18.     <div id="menu"> 
  19.         <ul> 
  20.             <li>Groupe lien 
  21.                 <ul> 
  22.                     <li>Lien</li> 
  23.                     <li>Lien</li> 
  24.                     <li>Lien</li> 
  25.                     <li>Lien</li> 
  26.                     <li>Lien</li> 
  27.                     <li>Lien</li> 
  28.                 </ul> 
  29.             </li> 
  30.             <li>Groupe lien 
  31.                 <ul> 
  32.                     <li>Lien</li> 
  33.                     <li>Lien</li> 
  34.                     <li>Lien</li> 
  35.                     <li>Lien</li> 
  36.                     <li>Lien</li> 
  37.                     <li>Lien</li> 
  38.                 </ul> 
  39.             </li> 
  40.             <li>Groupe lien 
  41.                 <ul> 
  42.                     <li>Lien</li> 
  43.                     <li>Lien</li> 
  44.                     <li>Lien</li> 
  45.                     <li>Lien</li> 
  46.                     <li>Lien</li> 
  47.                     <li>Lien</li> 
  48.                 </ul> 
  49.             </li> 
  50.             <li>Groupe lien 
  51.                 <ul> 
  52.                     <li>Lien</li> 
  53.                     <li>Lien</li> 
  54.                     <li>Lien</li> 
  55.                     <li>Lien</li> 
  56.                     <li>Lien</li> 
  57.                     <li>Lien</li> 
  58.                 </ul> 
  59.             </li> 
  60.             <li>Groupe lien 
  61.                 <ul> 
  62.                     <li>Lien</li> 
  63.                     <li>Lien</li> 
  64.                     <li>Lien</li> 
  65.                     <li>Lien</li> 
  66.                     <li>Lien</li> 
  67.                     <li>Lien</li> 
  68.                 </ul> 
  69.             </li> 
  70.         </ul> 
  71.     </div> 
  72.   
  73.     <div id="content"> 
  74.         <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed aliquam est at lorem. Ut eget orci. Sed tortor. Sed sapien metus, vulputate a, ornare quis, faucibus id, libero.  
  75. Quisque elementum lobortis orci. Aliquam vehicula. Suspendisse vestibulum tempor enim. Sed eu tortor eget mauris gravida volutpat. Morbi ornare, mauris nec aliquet commodo, eros magna interdum odio, sed dictum eros est id nisl.  
  76. Proin varius leo sit amet neque. Aliquam elementum est et urna. Sed a ante id nunc consequat vehicula.</p> 
  77.  <p>Sed ligula augue, volutpat eget, vehicula sit amet, auctor non, velit. Nunc sodales blandit elit. Vestibulum et urna. Vivamus suscipit, ligula et fringilla tincidunt, turpis leo pellentesque erat, quis elementum 
  78.  est est id mauris. Pellentesque sem turpis, mattis sed, rhoncus quis, blandit vel, sem. Nulla sed nisi non lorem lobortis egestas. Suspendisse elit diam, iaculis a, 
  79.  dapibus in, vehicula a, dui. Nulla facilisi. Vivamus rutrum euismod nunc. Praesent non arcu in enim sagittis rhoncus.</p> 
  80.  <p>Fusce lorem nisi, feugiat ut, rutrum sit amet, porttitor vel, est. Proin a nunc vel augue blandit consectetur. Donec non urna. Fusce vel dui. Duis quis ante. Duis non orci. Nullam vestibulum dolor.  
  81. Quisque vulputate porta lorem. Vivamus hendrerit. Vivamus quam. Mauris lacinia. Proin hendrerit. In hac habitasse platea dictumst. Morbi leo odio, porta in, tincidunt eget, sagittis nec, est.  
  82. Ut imperdiet, lacus a luctus laoreet, arcu erat viverra quam, eget elementum dolor ipsum vel lectus. Ut ac urna et urna feugiat dictum. Phasellus bibendum eros scelerisque nunc. Donec at sem id ante sagittis ultricies. Morbi ut velit.</p> 
  83.     </div> 
  84.   
  85.     <div id="slidebar"> 
  86.         <ul> 
  87.             <li>Groupe lien 
  88.                 <ul> 
  89.                     <li>Lien</li> 
  90.                     <li>Lien</li> 
  91.                     <li>Lien</li> 
  92.                     <li>Lien</li> 
  93.                     <li>Lien</li> 
  94.                     <li>Lien</li> 
  95.                 </ul> 
  96.             </li> 
  97.             <li>Groupe lien 
  98.                 <ul> 
  99.                     <li>Lien</li> 
  100.                     <li>Lien</li> 
  101.                     <li>Lien</li> 
  102.                     <li>Lien</li> 
  103.                     <li>Lien</li> 
  104.                     <li>Lien</li> 
  105.                 </ul> 
  106.             </li> 
  107.             <li>Groupe lien 
  108.                 <ul> 
  109.                     <li>Lien</li> 
  110.                     <li>Lien</li> 
  111.                     <li>Lien</li> 
  112.                     <li>Lien</li> 
  113.                     <li>Lien</li> 
  114.                     <li>Lien</li> 
  115.                 </ul> 
  116.             </li> 
  117.         </ul> 
  118.     </div> 
  119. </div> 
  120. <div id="footer"></div> 
  121. </body> 
  122. </html> 

Il n'y a rien de compliqué ici, puisque nous définissons trois <div> avec leur contenu respectif. On ajoute un en-tête et un pied de page pour la forme générale.

III. Le CSS

Le but ici est de déclarer nos trois <div> comme étant les cellules d'un tableau. En effet, vous avez déjà pu remarquer que lorsque l'on utilise un tableau HTML, les cellules de chaque ligne prennent la hauteur de la cellule la plus grande.

Les <div>, elles, ne fonctionnent pas de la même manière quand elles sont de type block, puisque leurs dimensions s'adaptent aussi bien en largeur, qu'en hauteur, suivant le contenu qu'elles encadrent. En revanche, lorsque les <div> sont de type inline, leur type par defaut, la largeur occupe tout l'espace donné par l'élément parent.

C'est pourquoi, l'idée est de dire au navigateur que ces <div> doivent agir comme si elles étaient des cellules de tableau.

Pour réaliser ceci, il faut utiliser la propriété CSS display à la valeur table-cell.

Petit rappel sur cette propriété :
Display permet d'indiquer le mode de rendu d'un élément HTML. Les valeurs les plus couramment utilisées sont :

  • none : pour masquer l'élément ;
  • block : placé sur la même ligne verticale ;
  • inline : placé sur la même ligne horizontale.

Tout d'abord, le code CSS général, qui sera utilisé par tous les navigateurs (ou presque, comme vu plus haut) et qui met en forme la page.

On définit la page avec une largeur de 70 % de la taille de l'écran que l'on centre en mettant des marges droite et gauche en automatique. Chacune des marges prenant pour valeur la moitié de la place restante, soit 15 % ( (70 - 30) /2 ).
Et on ne veut pas de marges internes (préférence personnelle) :

 
Sélectionnez
body {
    margin-left: auto;
    margin-right: auto;
    width: 70%;
    padding: 0;
}

Pour l'en-tête, on lui dit de prendre 100 % de la largeur (donc les 70 % de la page) et une hauteur de 150 pixels.

On fait la même chose pour le pied de page avec une hauteur de 30 pixels.

 
Sélectionnez
#header {
 width: 100%;
 height: 150px;
 background-color: #536893;
}
 
#footer {
 width: 100%;
 height: 30px;
 background-color: #ff5626;
}

Pour le menu de gauche, on définit la <div> comme une cellule de 15 % de largeur. Ce sera donc la première cellule de notre tableau fictif avec le display : table-cell.

 
Sélectionnez
#menu {
 background-color: #638cde;
 color: #ffffff;
 width: 15%;
 display: table-cell;
}

Pour le contenu, on procède de la même manière en définissant le conteneur comme une cellule et on lui applique une largeur de 70 %. Notre deuxième cellule :

 
Sélectionnez
#content {
 background-color: #dbeaf9;
 width: 70%;
 display: table-cell;
}

Encore un peu d'esthétique en appliquant une marge interne de 10 pixels pour décoller les paragraphes des bordures des <div>.

 
Sélectionnez
#content p {
    padding: 10px;
}

Et enfin, notre dernière cellule pour le menu de droite en prenant les 15 derniers pour cent qu'il reste.

 
Sélectionnez
#slidebar {
 background-color: #638cde;
 color: #ffffff;
 width: 15%;
 display: table-cell;
}

On met une légère mise en forme pour les listes. Pas de marge interne et une marge en bas et à gauche de 15 pixels.

 
Sélectionnez
ul {
    padding: 0;
    margin: 0 0 15px 15px;
}

Comme vous pouvez le voir, le principe est relativement simple et ne requiert pas énormément de temps pour se mettre en place.

Pour IE 7 il faut jongler un petit peu car il ne comprend table-cell que pour les éléments de type inline. Or ici ce n'est pas le cas, puisque nous utilisons les éléments <div> qui sont de type block, par défaut. Si les éléments à placer en colonnes avaient été de type inline, il aurait fallu mettre un display : inline-block et c'est pris en compte par IE 7 et versions précédentes.


Il faut donc transformer chaque <div> en élément flottant avec la propriété float à la valeur left.

Parce que comme on le sait tous, le fait de mettre un élément en flottant permet à celui-ci de sortir du flux et de venir se positionner le plus à droite (float : right) ou le plus à gauche (float : left) possible dans son conteneur. Dans notre cas à nous, nous voudrions que tous les blocs se placent à gauche. C'est pour cette raison que l'on définit toutes les <div> en flottant à gauche grâce à float : left;.

On n'oublie pas non plus d'appliquer un overflow hidden pour que la marge externe s'applique. On parle alors de contexte de formatage.

style-ie7.css
Sélectionnez
  1. /*  
  2.  * On applique une marge interne positive et une marge externe négative égales 
  3.  * sur les blocs de façon à ce qu'ils aient la même hauteur. 
  4.  * Ne fonctionne que si l'on crée un contexte de formatage avec overflow (voir ci-dessous) 
  5.  */ 
  6. #container div { 
  7.     margin-bottom: -1500px; /* peu importe les unités */ 
  8.     padding-bottom: 1500px; 
  9.     float: left; /* On positionne chaque div les unes à la droite des autres avec un float */ 
  10. } 
  11.   
  12. /* On crée un contexte de formatage pour que les marges ne débordent pas du conteneur */ 
  13. #container { 
  14.     overflow: hidden; 
  15. } 

Ainsi, chaque <div> sera l'une à côté de l'autre grâce à ce positionnement flottant.

Voyons maintenant quelques explications sur le contexte de formatage.

Il faut se souvenir que les éléments flottants sortent du flux de leur conteneur, ils se chevauchent. C'est pour cette raison que, parfois, des éléments flottants ne tiennent plus dans l'élément parent. Ainsi, mettre un overflow à hidden empêche un élément flottant de dépasser.

Pour plus de renseignements concernant le contexte de formatage, je vous invite à lire cet article de Bruno Bichet. Il montre les différentes façons de mettre en place un contexte.

Voici donc à quoi ressemble notre feuille de style principale :

 
CacherSélectionnez

Quant à IE 6, il bénéficie aussi de sa feuille de style à cause du HasLayout.
Pour plus d'explications concernant le HasLayout voici celle de Microsoft.

style-ie6.css
Sélectionnez
  1. /* HasLayout IE 6 
  2.  * Permet de corriger un bug de rendu connu 
  3.  */ 
  4. #container { 
  5.     height: 1%; 
  6. } 

Et voilà, c'est tout pour le CSS.

Vous pouvez voir un exemple de cet article ici.

IV. Conclusion et remerciement

Le correctif pour Internet Explorer est tiré de ce tutoriel : http://css.britoweb.info/post/Creer-des-colonnes-de-meme-hauteur-en-CSS (lien cassé).


Je tiens à remercier ClaudeLELOUP pour sa relecture orthographique attentive, ainsi qu'à FirePrawn, 12monkeys, Bovino et Candygirl pour leur relecture technique.