Vous êtes ici : Accueil du blogCSS, Responsive » Fixer son footer en bas de page grâce à Flexbox

Fixer son footer en bas de page grâce à Flexbox

Vous connaissez sans doute la technique du « sticky footer » via positionnement absolu (ou fixed). L’inconvénient de cette méthode est qu’elle nécessite de fixer la hauteur du footer. Et ça, c’est embêtant pour la maintenance et le responsive (hauteur variable en fonction du contenu et/ou du device).

Voici une solution via Flexbox qui permet de positionner le footer en bas de page, tout en lui permettant de conserver une hauteur fluide.

Modern browsers

Solution fonctionnelle sur tous les navigateurs « modernes » (Firefox 20+, Chrome 29+, Edge) :

<div id="page">
	<div id="header"></div>
	<div id="content"></div>
	<div id="footer"></div>
</div>
#page {
	min-height:100vh; /* 1 */
	display:flex; /* 2 */
	flex-direction:column; /* 3 */
}

#content {
	flex-grow:1; /* 4 */
}
  1. On définit un conteneur global #page ayant une hauteur au minimum égale à la hauteur du viewport :
    100vh = 100% viewport height.
  2. Via display:flex on lui précise un « contexte flex » (en anglais « flex layout»).
  3. Ce contexte est transmis aux enfants directs auxquels on spécifie un affichage en colonne, grâce à flex-direction.
  4. Enfin, flex-grow:1 indique à #content que tout l’espace disponible doit être occupé. Cela permettra de pousser le footer en bas de page et d’obtenir ainsi l’effet recherché.

Voir la démo

Je vous conseille fortement d’utiliser un conteneur global, comme ici avec #page, pour réaliser ce genre de mise en page. En effet, définir un contexte flex directement sur <body> comme on peut le voir sur d’autres d’articles peut causer des problèmes avec les plugins qui créent des éléments en bas de page avant </body> (popup, autocomplete, etc.). Ces éléments risquent de ne pas s’afficher correctement, à cause du contexte flex hérité. Just saying.

Old browsers

Avant de passer au code voici quelques arguments qui, je l’espère, vous feront réfléchir quant à une éventuelle implémentation du sticky footer sur les vieux navigateurs :

  • Ils représentent moins de 10% de vos visiteurs (StatCounter, Worldwide, Août 2016).
  • Un navigateur obsolète peut être la conséquence de matériel obsolète. Et sur un vieil écran, la résolution est tellement faible qu’il y a des chances pour que l’effet sticky ne soit pas perceptible.
  • Est-ce que le budget le permet ? Surtout si vous partez d’un projet existant, la solution suivante entrainant une modification de la structure (ce qui peut impacter le reste du site).
  • Les utilisateurs sous IE10 ou Safari 6 le méritent-ils ? C’est l’argument en carton, mais j’en connais qui sont capables de le défendre. :)

Si ces arguments n’ont pas suffi à vous convaincre (vous, votre boss, votre client), voici la solution permettant d’étendre le support aux oldies (Firefox 20+, Chrome 21+, IE10+, Safari 6.1+, Opera 12.1+) :

<div class="ie-stickyFooter">
	<div id="page">
		<div id="header"></div>
		<div id="content"></div>
		<div id="footer"></div>
	</div>
</div>
.ie-stickyFooter { /* 1 */
	display:flex;
}

#page {
	width:100%; /* 2 */
	min-height:100vh;
	display:-webkit-flex; /* 3 */
	display:flex;
	-webkit-flex-direction:column; /* 3 */
	flex-direction:column;
}

#content {
	-webkit-flex-grow:1; /* 3 */
	flex-grow:1;
}
  1. Sur IE10/11, les enfants flex ignorent la hauteur du parent quand celui-ci associe conjointement min-height et flex layout (voir le bug report). L’utilisation d’un conteneur supplémentaire permet de corriger le problème.
  2. Cette instruction permet de normaliser la largeur du conteneur, quelque peu dérouté par le double contexte flex. Son utilisation est également nécessaire pour faire fonctionner correctement max-width, au cas où vous voudriez centrer horizontalement le gabarit.
  3. L’emploi du préfixe -webkit- permet d’élargir le support aux anciennes versions des navigateurs Webkit (Chrome, Safari, Opera).

Voir la démo

Ressources utiles :

Laisser un commentaire

Balises HTML autorisées dans la rédaction du message :
<strong> <a> <code> <q>

Les champs marqués d'une étoile sont obligatoires.

Current month ye@r day *