Colonnes de hauteur égale en CSS

· 6 min de lecture

Publication originale

Cet article a été publié à l'origine le 17 mars 2009 sur The Standard, le blogue de Raincity Studios, sous la signature « Hubert Florin ». Cet article reflète le contexte et les outils de l'époque; certains liens et services mentionnés n'existent plus. Article traduit de l'anglais. La version anglaise est le texte original.

Voir l'original dans l'Internet Archive

J'ai aussi publié ce billet sur mon blogue personnel, où vous pouvez aussi le lire en français

La recherche d'une technique offrant de vraies colonnes de hauteur égale ne mène nulle part, parce que nous n'avons pas de contrôle vertical complet dans les implémentations actuelles de CSS 2.1 d'un navigateur à l'autre

C'est ainsi qu'Ingo Chao commence son article présentant une méthode pour créer une mise en page en CSS avec des colonnes de hauteur égale. Obtenir des colonnes de même hauteur n'est pas toujours facile si vous ne comptez que sur CSS et, mis à part la méthode des fausses colonnes, je ne connais aucune façon stable de créer des colonnes de hauteur égale uniquement en CSS sans balisage supplémentaire.

Après avoir poussé un peu plus mes recherches sur le sujet, les solutions que j'ai trouvées étaient soit boguées, soit compliquées à mettre en œuvre; j'ai donc décidé d'expérimenter avec toutes ces méthodes pour en créer une simple et souple, qui chargerait le contenu avant les barres latérales, qui pourrait être fluide, fixe ou en grille et, bien sûr, qui fonctionnerait dans tous les navigateurs.

Je dois avouer que je pensais VRAIMENT inventer quelque chose, jusqu'à ce que je tombe sur cet article de Paul O'Brien. Sa méthode utilise le même truc de positionnement que celui que j'utilise pour les colonnes.. Ma seule réelle contribution serait de fusionner une méthode de type « Holy Grail » avec la méthode d'O'Brien. La mise en page finale peut être modifiée très facilement, passer de fluide à fixe ou en grille au besoin, charge le contenu avant les barres latérales (contenu->gauche->droite), peut être adaptée à autant de colonnes que vous voulez, fonctionne dans à peu près tous les navigateurs et, bien sûr, simule des colonnes de hauteur égale.

En bref

Comme dans la méthode d'O'Brien, j'utilise un <div> supplémentaire (je sais, honte à moi!) pour chaque colonne. Je les positionne ensuite en absolu, et c'est là que la vraie magie opère. Un bloc normal ayant une hauteur de 100 % ne peut remplir son conteneur que si ce conteneur a lui-même une hauteur. Mais cela ne s'applique pas si le bloc est positionné en absolu. Donc, si je positionne le bloc en bas et que je lui donne une hauteur de 100 %, il crée pour la colonne un arrière-plan qui s'étend jusqu'au pied de page. Faites cela pour chaque colonne, et vous obtenez une mise en page avec des colonnes de hauteur égale.

Voici quelques exemples des mises en page finales, et quelques diapositives HTML qui présentent la méthode étape par étape.

Le concept étape par étape

[Chaque étape était illustrée à l'origine par un diagramme.]

  1. Vous commencez avec une mise en page normale.
  2. Nous n'utiliserons pas les « vraies » colonnes pour obtenir un arrière-plan.
  3. Nous ajoutons plutôt trois <div> au bas de la page, qui ont la même classe que leurs colonnes respectives, de sorte que les <div> sont alignés avec leurs colonnes.
  4. Les <div> sont positionnés en absolu.
  5. Donner à chaque <div> une hauteur de 100 % et les positionner en bas crée les colonnes pleine hauteur.
  6. Ramenez le contenu au premier plan avec z-index:2; et voilà !

Regard plus attentif sur le code

Voici le balisage d'origine que j'utilise. Il pourrait être un peu plus léger si vous considérez qu'IE ne vaut pas la peine qu'on s'en préoccupe, puisque #main ne sert qu'à régler un problème de dégagement (clearing).

<div id="page">
<div id="header">...</div>
<div id="main">
<div id="content">
<div id="content-inner" class="column center">...</div>
</div>
<div id="left" class="column left">...</div>
<div id="right" class="column right">...</div>
</div> <!-- /main -->
<div id="footer">...</div>
</div><!-- /page -->

Voici une représentation graphique des <div> :

[Diagramme de la structure des <div> affiché à l'origine ici.]

La mise en page de base

Regardons de plus près comment la mise en page est créée. D'abord, je commence toujours par une simple réinitialisation des styles du navigateur.

*{
margin:0;
padding:0;
}

Nous pouvons ensuite commencer à monter la mise en page. Ajoutons quelques couleurs pour voir ce que nous faisons :

#header, #footer{background-color: #ccc;}
#left{background-color:#d7ecff;}
#right{background-color:#daffc6;}
#content-inner{background-color:#fff2d7;}

Définition de la largeur des barres latérales.

.left {
width: 220px;
}
.right{
width: 150px;
}

Préparons ensuite le contenu pour compenser les barres latérales une fois qu'elles seront bien positionnées.

#content-inner {
margin-left: 220px;
margin-right: 150px;
}

Ramenons les barres latérales au même niveau que le contenu, au moyen de #content et en faisant flotter toutes les colonnes.

#content {
float:left;
width:100%;
margin-right:-100%;
}
.column {
float:left;
}

Une petite assurance pour qu'IE fonctionne correctement... on retire le flottement de la colonne centrale.

#content-inner {
float:none;
margin-left: 220px;
margin-right: 150px;
}

La barre latérale droite ne devrait pas flotter à gauche, mais à droite.

.right{
float:right;
width: 150px;
}

Dernière touche, le pied de page doit dégager (clear) les colonnes. Plus quelques styles.

#footer, #header{
clear:both;
text-align:center;
font-size:2em;
}

La mise en page est terminée; vous devriez donc avoir quelque chose comme ceci. Jusqu'ici, tout va bien : ça fonctionne dans tous les navigateurs sans aucun bidouillage. Mais vous remarquerez que toutes les colonnes ont une hauteur différente, et c'est ce que nous allons maintenant corriger.

Les colonnes de hauteur égale

D'abord, ajoutons les <div> vides (je rougis). Remarquez que nous donnons la même classe right, left ou center aux <div> vides pour qu'ils se comportent comme leurs colonnes correspondantes.

<div id="page">
<div id="header">...</div>
<div id="main">
<div id="content">
<div id="content-inner" class="column center">...</div>
</div>
<div id="left" class="column left">...</div>
<div id="right" class="column right">...</div>
</div> <!-- /main -->
<!-- These are used to create the columns background -->
<div id="bgcenter" class="bg center"></div>
<div id="bgleft" class="bg left"></div>
<div id="bgright" class="bg right"></div>
<div id="footer">...</div>
</div><!-- /page -->

Comme ces <div> sont vides, vous ne devriez remarquer aucune différence dans votre mise en page. Pour voir notre travail, nous allons modifier les règles de couleur pour qu'elles s'appliquent à ces <div> vides.

#bgleft{background-color:#d7ecff;}
#bgright{background-color:#daffc6;}
#bgcenter{background-color:#fff2d7;}

Maintenant que les couleurs sont appliquées aux futures « fausses colonnes », que la magie commence. D'abord, comme nous allons positionner les fausses colonnes, nous redéfinissons leur élément de référence relatif sur l'élément #page.

#page{
position:relative;
}

Nous pouvons maintenant positionner les fausses colonnes et leur donner une hauteur. Il est très important de les positionner en bas, pour la compatibilité entre navigateurs.

.bg{
position:absolute;
bottom:0;
height:100%;
}

Nous pouvons ensuite remplacer ces règles générales pour chaque colonne afin de les positionner correctement et avec la bonne largeur.

#bgleft{
left:0;
}
#bgright{
right:0;
}
#bgcenter{
right:0;
width:100%;
}

Remarquez que nous pouvons donner une largeur de 100 % au contenu puisqu'il est chargé avant les autres colonnes; il apparaîtra donc sous elles. Maintenant tout va bien, sauf que les fausses colonnes s'affichent par-dessus le contenu... pas bon; alors, pour ramener le contenu au premier plan, il me suffit de jouer avec le z-index du contenu :

#content, #left, #right, #header, #footer{
position:relative;
z-index:2;
}

Et voilà! Toutes les colonnes semblent avoir exactement la même hauteur, et vous pouvez même styliser chacune d'elles indépendamment. Mais bien sûr, comme je l'ai dit un peu plus tôt, toutes les versions d'IE antérieures à la version 8 ont besoin d'un petit ajustement. Rien de grave toutefois... placez ceci dans votre <head> et tout devrait rentrer dans l'ordre !

<!--[if lt IE 8]>
<style type="text/css">
/* Only Hack for IE */
#main, #page{ height:1%; }
.bg{ height:1000em; }
</style>
<![endif]-->

J'ai préparé quelques exemples de cette méthode, avec une largeur fluide ou fixe, et même un « exemple de grille fluide ». Outre le balisage supplémentaire, le seul inconvénient que je vois à cette méthode, c'est que l'en-tête et le pied de page doivent masquer les colonnes. Ça peut aller pour des projets simples, mais c'est peut-être un peu plus délicat pour des mises en page plus complexes.

J'ai aussi travaillé à intégrer cette méthode à une mise en page pleine hauteur, pour que le pied de page reste au bas de la fenêtre si la page n'est pas assez longue. Le résultat est assez stable, sauf dans Opera... il reste du travail, mais on se rapproche beaucoup d'une mise en page complète et souple, uniquement en CSS.

Références

Votre entreprise mérite d'être trouvée.

Parlez-nous de votre projet. Nous vous répondons en français ou en anglais, et nous nous déplaçons partout dans la MRC de Papineau.

Affichage

Vos choix restent dans ce navigateur. Rien n'est envoyé.

Taille du texte
100 %
Couleurs
Lecture
Autres aides
Accessibilité du site