Les pieds (de page) dans le plat

Par Bobby van der Sluis

Un des atouts de la méthode traditionnelle de mise en page par tableaux est qu'elle vous permet de créer très facilement des designs fluides. Si vous souhaitez centrer verticalement du contenu, ou fixer un pied de page en bas de la fenêtre du navigateur, il vous suffit d'inclure un tableau principal doté d'une largeur de 100% et d'y positionner vos éléments.

Avec les standards du web, ce n'est plus possible. La propriété height des tableaux est déclassée en XHTML, et les normes actuelles recommandent d'éviter l'utilisation de tableaux pour la mise en page. Pour séparer structure et présentation, CSS est tout indiqué - mais si vous voulez utiliser CSS pour le positionnement vertical, vous allez vous heurter à des défaillances chez certains des navigateurs principaux.

Cet article étudie les méthodes grâce auxquelles vous pouvez positionner des pieds de page en respectant les standards, mais les mêmes techniques peuvent être utilisées pour positionner verticalement d'autres éléments. Nombre de designs contiennent un pied de page qui est placé directement à la suite de la zone de contenu, sauf si le contenu et le pied de page ne remplissent pas à eux deux la fenêtre. Dans ce cas, le pied de page sera positionné au bas de la fenêtre du navigateur.

Positionnement absolu dans un bloc relatif

Imaginez un conteneur de largeur fixe. Le conteneur est constitué d'une quantité variable de contenu, et il est suivi d'un pied de page de largeur fixe. Quand vous ajoutez du contenu, la hauteur du conteneur augmente; quand vous en retirez, le conteneur rétrécit.

Si vous créez un conteneur en position relative et y insérez un bloc de contenu, ce dernier suivra par défaut le flux normal dans le conteneur, entraînant une augmentation ou une réduction de la hauteur de son bloc parent, selon son contenu. Un des points forts de la position relative est que vous pouvez y inclure des éléments en position absolue. Cela permet d'inclure un bloc de pied de page et de le positionner de façon absolue, afin qu'il "colle" au bas du contenu. Votre balisage ressemble à ceci :

<div id="container">
    <div id="content">...</div>

    <div id="footer">...<div>
</div>

Et votre feuille de style à ceci :

#container {
    position: relative;
        }

#footer {
    position: absolute;
    bottom: 0;
        }

Cependant, les éléments en position absolue sont retirés du flux normal et sont placés au-dessus des éléments du flux normal. Comme vous ne voulez pas que votre pied de page chevauche votre contenu, vous pouvez ajouter une valeur au padding-bottom du bloc de contenu, pour compenser la hauteur du pied de page. Vous pouvez voir le résultat sur l'exemple 1.

Cette étape ne fonctionne pas correctement avec Internet Explorer 5.x/Windows. Pour ces navigateurs, un bloc enfant positionné en absolu perd sa position si la hauteur du bloc parent n'est pas spécifiée. Nous allons nous intéresser à la hauteur du conteneur dans la prochaine étape.

Associer le contenu à la fenêtre du navigateur

Jusqu'à maintenant, la hauteur du conteneur est déterminée par la hauteur du bloc de contenu, ce qui est parfait s'il y a suffisamment de contenu pour remplir la hauteur de la fenêtre du navigateur. Si ce n'est pas le cas, vous aimeriez que le pied de page reste collé au bas de la fenêtre.

En CSS, c'est un effet facile à réaliser. Si vous donnez au conteneur une hauteur minimum de 100%, avec l'attribut min-height, la hauteur minimum du conteneur est égale à la hauteur de son élément parent : l'élément body. Vous spécifiez alors que la hauteur de l'élément body doit être égale à la hauteur de la fenêtre du navigateur en attribuant la valeur 100% à la fois à l'élément body et à l'élément html.

html, body {
    height: 100%;
}
#container {
    position: relative;
    min-height: 100%
}

Vous pouvez voir le résultat sur l'exemple 2. Voilà tout le code qui devrait être nécessaire pour positionner un pied de page avec CSS. Malheureusement, cette technique ne fonctionne pas avec Internet Explorer et Safari, à cause de leur non-prise en charge de l'attribut min-height.

Mais attendez une minute, cette technique fonctionne avec Internet Explorer 6, bien que ce navigateur ne supporte pas min-height (tout du moins pas selon les spécifications du W3C).

Il apparaît que si vous fixez la hauteur de l'élément body à 100%, sous Internet Explorer 6 (en mode Standards) le conteneur hérite de la hauteur de son bloc parent (en l'occurrence celle de la fenêtre du navigateur). La mauvaise implémentation de la valeur par défaut de visible pour l'attribut overflow dans Internet Explorer (sous Windows uniquement) fait que notre conteneur s'étend jusqu'à que son contenu s'y ajuste entièrement, au lieu de maintenir la hauteur de la fenêtre du navigateur navigateur à une valeur de 100%. Ces deux effets simultanés simulent de fait un attribut min-height.

Contourner certaines limitations

Internet Explorer 5.x/Windows affiche toujours une page en mode Quirks (NdT : mode "brouillon", non conforme aux standards). Si vous fixez la hauteur d'un élément bloc à 100%, du fait du mode brouillon, l'élément utilise la hauteur de la fenêtre du navigateur. Mais si alors vous ajoutiez simplement une hauteur de 100% au conteneur, cela aurait pour effet de régler le problème du premier exemple, et ferait également fonctionner la technique dans IE5/Windows. Notez que si vous fixez la hauteur du conteneur à 100%, un affichage selon le mode Standards affichera tout de même le pied de page collé au bas de la fenêtre du navigateur.

Grâce au box model hack, vous pouvez appliquer des règles de style à Internet Explorer 5.x/Windows uniquement. Vous devez définir la hauteur du conteneur de la façon suivante :

#container {
    position: relative;
    min-height: 100%;
    height: 100%;
    voice-family: "\"}\"";
    voice-family: inherit;
    height: auto;
}

html>body #container {
    height: auto;
}

Vous pouvez voir le résultat sur l'exemple 3. L'exemple 3 ne fonctionne pas avec Internet Explorer 5.x/Mac et Safari, mais il s'y dégrade élégamment : le pied de page sera toujours placé en bas du bloc de contenu.

Microsoft a stoppé le développement d'Internet Explorer sur la plateforme Mac. J'espère que Safari d'Apple prendra bientôt en charge l'attribut min-height. En attendant, que faire si vous souhaitez que tout fonctionne dans Safari ou Internet Explorer 5/Mac (ou, plus certainement, dans les deux) ? Existe-t-il des alternatives ? C'est drôle que vous le demandiez, parce que oui !

Mais que fait la cavalerie du W3C ?

Le W3C n'a malheureusement pas édicté de spécifications sur la manière de calculer la hauteur de la fenêtre de navigation ou d'éléments du document. Ils auraient probablement dû, les standards du DOM existant pour éviter aux développeurs de navigateur web d'avoir à créer ces spécifications eux-mêmes. Dans le cas présent, les développeurs ont été contraints de créer leurs propres attributs propriétaires.

Ainsi, si vous voulez utiliser un script pour positionner vos éléments en fonction de la taille de la fenêtre du navigateur, vous êtes condamné à utiliser des techniques propriétaires non conformes aux standards. La question est : est-ce une mauvaise chose que d'utiliser ces techniques là où on constate un manque de standardisation ?

Pour moi, cela dépend de la cohérence interne de ces techniques. Si elles peuvent combler les lacunes des standards du web et qu'elles sont utilisées de manière cohérente, je pense qu'elles doivent être considérées avec les mêmes égards que les spécifications du W3C.

Si vous avez le choix entre une méthode entièrement en CSS et une autre qui combine CSS et scripts, il est sage d'utiliser uniquement CSS. En principe, CSS doit s'occuper de la mise en forme et JavaScript du comportement. Toutefois, en particulier dans les cas où les standards sont assez mal pris en charge ou semblent insuffisants, l'utilisation du DOM et de JavaScript peut enrichir la mise en page de vos pages web. Dans ce cas, une utilisation combinée de CSS et de scripts peut être justifiée.

Utilisation du DOM pour calculer les hauteurs

Apparemment, les concepteurs des navigateurs web s'espionnaient les un les autres lorsqu'ils ont créé leurs spécifications propriétaires sur l'attribut height. Quoiqu'il en soit, le DOM nous offre la possibilité de calculer la hauteur de la fenêtre du navigateur et d'éléments du document. Bien que plusieurs navigateurs utilisent différents objets et propriétés, le script suivant déterminera correctement la hauteur de presque n'importe quel navigateur moderne :

function getWindowHeight() {
    var windowHeight=0;
    if (typeof(window.innerHeight)=='number') {
        windowHeight=window.innerHeight;
    }
    else {
     if (document.documentElement&&
       document.documentElement.clientHeight) {
         windowHeight = document.documentElement.clientHeight;
    }
    else {
     if (document.body&&document.body.clientHeight) {
         windowHeight=document.body.clientHeight;
      }
     }
    }
    return windowHeight;
}

La propriété window.innerHeight retourne la hauteur de la plupart des navigateurs modernes, excepté Internet Explorer. IE 6 utilise en mode Standards la propriété document.documentElement.clientHeight. La propriété document.body.clientHeight retourne la hauteur de la fenêtre des navigateurs de la famille IE 4+.

Avec document.getElementById(elementId).offsetHeight vous pouvez retrouver la hauteur de n'importe quel élément dans les navigateurs modernes.

Maintenant que vous pouvez calculer la hauteur de la fenêtre du navigateur et celles des éléments du document, vous êtes en mesure d'écrire une fonction pour positionner correctement votre pied de page.

Utilisation du DOM W3C pour positionner le pied de page

Ce n'est pas parce que vous utilisez JavaScript que vous ne pouvez pas utiliser CSS pour positionner vos éléments. Le DOM W3C peut faire le lien entre les règles de style et JavaScript. Cela signifie que vous pouvez écrire du JavaScript comme s'il s'agissait de CSS, avec quelques conditions et calculs de hauteurs.

Commencez par le balisage le plus rudimentaire de votre page, en créant un bloc pour le contenu et un bloc pour le pied de page :

<div id="content">...</div>
<div id="footer">...</div>

Si la hauteur des blocs de contenu et du pied de page réunis est supérieure à celle de la fenêtre du navigateur, le pied de page doit suivre le flux normal (position de type static). Si ce n'est pas le cas, votre script doit positionner le pied de page en bas de la fenêtre. Avec un positionnement relatif, vous pouvez faire descendre le pied de page par rapport à sa position dans le flux courant (vous pouvez également utiliser une position absolue pour le faire). Cela ressemble à CSS, n'est-ce pas ?

La fonction suivante réalise ce que nous venons de définir :

function setFooter() {
    if (document.getElementById) {
        var windowHeight=getWindowHeight();
        if (windowHeight>0) {
            var contentHeight=
            document.getElementById('content').offsetHeight;
            var footerElement=document.getElementById('footer');
            var footerHeight=footerElement.offsetHeight;
        if (windowHeight-(contentHeight+footerHeight)>=0) {
            footerElement.style.position='relative';
            footerElement.style.top=
            (windowHeight-(contentHeight+footerHeight))+'px';
        }
        else {
            footerElement.style.position='static';
        }
       }
      }
}

La fonction setFooter() pas à pas

D'abord, la fonction setFooter() détermine la hauteur de la fenêtre du navigateur et l'affecte à la variable windowHeight :

var windowHeight = getWindowHeight() ;

Ensuite, elle extrait la hauteur de l'élément contenu et de l'élément pied de page :

var contentHeight=document.getElementById('content').offsetHeight;
var footerElement=document.getElementById('footer');
var footerHeight=footerElement.offsetHeight;

Puis elle décide si la hauteur de la fenêtre du navigateur est plus grande que celle du contenu et du pied de page réunis :

if (windowHeight-(contentHeight+footerHeight)>=0)

Si c'est le cas, elle repositionne le pied de page en position relative (par rapport à sa place dans le flux normal) au bas de la page :

footerElement.style.position='relative';
footerElement.style.top=(windowHeight-(contentHeight+footerHeight))+'px';

Si par contre les éléments contenu et pied de page réunis remplissent la fenêtre du navigateur, l'élément pied de page est repositionné en static de façon à suivre le flux normal :

footerElement.style.position='static';

Pour faire fonctionner l'ensemble, incluez la fonction getWindowHeight() dans votre script et ajoutez deux fonctions qui appellent setFooter() lors du chargement ou du redimensionnement de la page web :

window.onload = function() {
setFooter();
}
window.onresize = function() {
setFooter();
}

Vous pouvez voir le résultat final sur l'exemple 4. Cependant il y a un petit hic. Safari est incapable de positionner un élément en position relative (ou absolue) si la fonction onload est appelée. Pour contourner ce problème, ajoutez la règle de style suivante :

#footer {
    position : relative;
}

Cette technique fonctionne sur tous les navigateurs modernes sans utiliser de hacks (NdT : contournements en CSS), un avantage temporaire sur la méthode du tout CSS. Si un navigateur ne sait pas calculer une des hauteurs, si JavaScript est désactivé ou si le navigateur ne supporte pas JavaScript, le pied de page suivra simplement le flux normal. Comme vous pouvez le voir, le balisage de la structure et la mise en forme sont toujours séparés, et votre balisage n'a pas gagné en complexité. Peut-être que le script tend à être plus prolixe que CSS, mais pas de façon très significative.

Réutiliser le concept

En effectuant simplement quelques modifications au niveau de la logique CSS, vous pouvez obtenir de multiples manières de positionner votre pied de page. Vous pouvez utiliser uniquement des éléments en positionnement relatif (exemple 5) ou en positionnement absolu (exemple 6).

La technique du script peut facilement être réutilisée pour d'autres problèmes de positionnement vertical. Imaginons que vous vouliez centrer verticalement un bloc de contenu dans la fenêtre du navigateur, en utilisant uniquement CSS. Vous pourriez aussi bien obtenir cet effet en réutilisant le script. Vous pouvez voir le résultat sur l'exemple 7.


Translated with the permission of A List Apart and the author[s].

Fiche technique

À propos de l'auteur

Bobby van der Sluis est un web designer et spécialiste en production basé à Amsterdam. Professionnellement, il participe à la création de sites pour des entreprises internationales basées aux Pays-Bas, comme Vodafone, ING Bank, HO, DSM et Randstad. Pendant son temps libre il se lance dans des expérimentations graphiques et travaille sur ses projets personnels.

Articles similaires

Voici la liste des dix articles les plus récents en rapport avec cet article :

Intermédiaire

CSS

© 2001-2016 Pompage Magazine et les auteurs originaux - Hébergé chez Nursit.com ! - RSS / ATOM - About this site