Objectif
Il s'agit de réaliser une mise en page extensible en hauteur, mais qui prenne au minimum toute la hauteur de la page. Le problème porte sur le positionnement du pied de page:
- celui-ci doit être poussé par le contenu lorsque le contenu est plus long que la hauteur de l'écran,
- mais il doit s'afficher tout en bas de l'écran lorsque le contenu est plus court.
Dans ce tutoriel, nous allons voir comment procéder pour obtenir ce résultat.
Un avertissement toutefois: ce type de mise en page peut être problématique pour certains utilisateurs, notamment dans le cas de l'utilisation d'une loupe d'écran… sans vue globale sur toute la page, l'utilisateur ne saura pas que celle-ci comporte un pied de page.
Structure (HTML)
<body> <div id="page"> <h1 id="premier-element">…</h1> … Autant de contenu que l'on voudra. … <p id="dernier-element">…</p> <div id="piedpage">Pied de page</div> </div> </body>
Important:
- le pied de page est placé à l'intérieur (autrement dit comme enfant direct) du bloc conteneur général… il peut être placé aussi bien au debut qu'à la fin de ce conteneur, selon les besoins de structuration de l'information, mais il est probable qu'il trouve sa place tout naturellement en fin de conteneur;
- les premiers et derniers éléments du bloc conteneur (hors pied de page) reçoivent un style spécifique, qui nous servira à corriger certaines subtilités de mise en page.
Mise en forme (CSS)
Étape n°1 : un conteneur sur toute la hauteur de la fenêtre
Nous voulons que le conteneur global (une div
portant l'identifiant "page") prenne systématiquement au moins 100% de la hauteur de la fenêtre. On peut réaliser ceci grâce à la propriété CSS min-height
, à condition d'avoir spécifié la hauteur des éléments html
et body
.
html, body { margin: 0; padding: 0; height: 100%; } div#page { width: 60%; margin: 0 auto; min-height: 100%; }
Dans la foulée, on a donné une largeur à ce conteneur, ce qui nous permet de le centrer grâce aux marges automatiques.
Mais nous avons un problème: Internet Explorer 6 ne reconnaît pas la propriété min-height
. Il s'agit alors de spécifier pour le bloc conteneur, et dans Internet Explorer uniquement, une hauteur de 100%, que le navigateur interprétera – à tort, bien sûr – comme une hauteur minimale et non comme une hauteur fixe.
<!--[if lte IE 6]> <style type="text/css"> div#page { height: 100%; } </style> <![endif]-->
Utiliser un hack CSS aurait été plus rapide, mais la solution des commentaires conditionnels est plus propre.
Étape n°2: positionner le pied de page
Nous allons maintenant positionner le pied de page pour qu'il se place tout en bas de son parent. Mais afin que ce dernier puisse servir de référent au pied de page, il faut qu'il soit lui-même positionné, soit en relatif, soit en absolu. Le plus simple et le moins contraignant est d'utiliser le positionnement relatif.
div#page { position: relative; } div#piedpage { position: absolute; bottom: 0; left: 0; width: 100%; }
Le bloc conteneur (div#page) positionné sert à la fois de référent pour le positionnement absolu (le bottom: 0;
) que pour la définition de la largeur du pied de page: width: 100%
correspond à 100% de la largeur du bloc conteneur. Sur ce dernier point, attention cependant aux bordures et autres espacements (border
et padding
) qui pourraient vous jouer de petits tours, si vous ne maîtrisez pas le modèle de boîte CSS.
Étape n°3: deux subtilités à prendre en compte
Il reste deux petites subtilités à prendre en compte, qui pourraient vous gêner autrement. Il s'agit:
- des problèmes liés à la fusion des marges;
- d'un problème lié au positionnement absolu du pied de page.
Pour la fusion des marges, il s'agit d'empêcher les marges verticales des premier et dernier éléments (hors pied de page) enfants du conteneur de se transmettre aux marges verticales du conteneur. Par exemple, si le premier élément (disons un titre de niveau 1) dans <div id="page">…</div>
a une marge haute de 1em, et que le conteneur ne possède ni bordure, ni espacement interne (padding
), alors cette marge sera transmise au conteneur. Plus d'infos sur la fusion des marges par ici: blocs imbriqués et fusion des marges.
On donne un style particulier au premier et au dernier élément (hors pied de page) enfants du bloc conteneur:
div#page #premier-element { margin-top: 0; } div#page #dernier-element { margin-bottom: 0; }
Maintenant que ceci est réglé, nous avons un deuxième problème: le pied de page, positionné en absolu, vient recouvrir la fin du contenu lorsque celui-ci est suffisamment long. On corrigera ce problème assez facilement, à l'aide d'un padding sur le dernier élément de contenu:
div#page #dernier-element { padding-bottom: 4em; }
Attention: la hauteur de ce padding devra être relative à la hauteur du pied de page! Il s'agit donc de connaître à l'avance la hauteur de ce pied de page, soit dans une unité fixe (px), soit dans une unité variable (em): c'est la seule restriction importante de la méthode que nous venons d'exposer.
Voilà, nous avons la base de notre mise en page!
Pour le code CSS complet, voir la source de cette page. ;)