Page d'accueil | Contact | Plan | Droits d'auteur | Login membres

Visitez quelques sites des membres d'Eklesia.net

Niveau avancé
Fixer la largeur minimum et maximum d’une page sous Internet Explorer

Internet Explorer (IE/win) ne reconnaît pas les propriétés CSS min-width et max-width. Il est pourtant possible en utilisant une "propriété dynamique" (une fonction spécifique à IE, ce que nous aurions souhaité éviter) d’obtenir un résultat voisin et, dans l’exemple que nous allons voir, d’encadrer une mise en page fluide entre deux limites au moyen d’une expression du type :


width:expression(document.body.clientWidth > 950  ? "950px" : "740px" );

Internet Explorer (IE) ne gère pas les propriétés min-width et max-width telles que définies dans la "spécification CSS2" éditée par le W3C. Cela est particulièrement gênant pour les concepteurs de pages Web dans un univers marqué par la diversité croissante de la définition des écrans utilisés par les internautes :

  • Une page d’une largeur de l’ordre de 750 pixels, conçue pour être affichée sur des écrans 800x600, peut sembler perdue au milieu d’un écran de portable dont la largeur atteint 1280 pixels voire plus.
  • Des pages prévues pour une définition de 1024x768 (ayant, par exemple, une largeur de l’ordre de 1000 pixels) sont inconfortables à lire sur des écrans 800x600 encore nombreux, l’internaute n’ayant qu’une vue partielle du contenu présenté.

Une réponse peut être une mise en page fluide (la largeur de la page est définie en pourcentage, par exemple 100%, de l’espace disponible dans la fenêtre de son navigateur). Mais, sans limite supérieure, les pages peuvent s’étirer de manière excessive et perdrent en lisibilité. De même, sans limite inférieure, ces pages "fluides" peuvent "s’écraser" et perdre en cohérence.

Face à ce constat, une réponse intéressante, que nous allons explorer plus avant ici, peut consister à proposer :

  • une mise en page fluide,
  • une limite inférieure exprimée en pixels (par exemple 740px),
  • une limite supérieure également exprimée en pixels (par exemple 950px),
  • centrer le contenu lorsque la largeur de la fenêtre du navigateur dépasse la limite supérieure fixée.

Pour obtenir une telle mise en page, le premier élement inclu dans le body sera une div#page :


<body>
   <div id="page">

Cette division se verra associer les règles suivantes dans la feuille de style :


#page  {
        margin: 0 auto;  /* zéro ou une autre valeur */
        width: 100%;
        min-width: 740px;
        max-width: 950px;
     }

Bien, mais le concepteur Web bute alors sur le fait que ce "grand dadais" d’Internet Explorer, toutes versions confondues, ne supporte pas ces propriétés min-width et max-width.

Une solution propriétaire pour IE

En fait, une solution propriétaire existe. Elle permet à Internet Explorer d’obtenir un résultat analogue. Un étudiant danois, Svend Tofte, a popularisé cette piste dans un article intitulé "max-width in Internet Explorer" (en). Il recourt à des instructions propres à Internet Explorer appelées "propriétés dynamiques" (en).

Celles-ci sont construites comme suit :

  • la propriété visée : ici "width :"
  • suivie d’une expression Jscript (le JavaScript de Microsoft), voire Vbscript [1], entre parenthèses.
  • L’expression Jscript est de la forme : (condition ? alors : sinon).
  • La comparaison se réalise sur la propriété dynamique clientWidth appliquée à l’élément body. Cette expression retourne, grosso-modo, la largeur de la fenêtre exprimée en pixels (précisément, la largeur de l’objet, ici body, en incluant le padding mais en excluant les marges, bordures et l’éventuelle barre de défilement [2]). A noter que la comparaison ne peut être réalisée qu’en pixels, ce qui constitue une limite importante.

De plus, ces informations :

  • sont saisies comme une règle de feuille de style, dans une feuille de style si nous le souhaitons, sans que cela ne perturbe les autres navigateurs (même si nous intégrerons bientôt cette mention dans un "commentaire conditionnel"),
  • fonctionnent même si le JavaScript (alias "Active Scripting") est désactivée dans le paramétrage d’Internet Explorer.

A la fin de son article, sous le titre "With pixels (easier !)", Svend Tofte prend l’exemple suivant :

max-width: 800px;
width:expression(document.body.clientWidth > 800? "800px" : "auto" );

Il indique de plus une seconde expression permettant de définir une largeur minimale :

min-width: 800px;
width:expression(document.body.clientWidth < 800 ? "800px" : "auto" );

Première tentative : cumuler ces 2 expressions

Pour définir à la fois un minimum (740px dans mon exemple) et un maximum (950px) à la largeur de ma div#page, une voie serait de cumuler ces 2 expressions :


width: 100%;
max-width: 950px;
min-width: 740px;
width:expression(document.body.clientWidth > 950 ? "950px" : "auto" );
width:expression(document.body.clientWidth < 740 ? "740px" : "auto" );

Mais, à travers mes tests, le cumul de ces 2 mentions ne se passe pas bien du tout. Deux problèmes apparaissent :

  1. Internet Explorer 6 se plante lorsque la fenêtre atteint la dimension minimum,
  2. seule la seconde ligne est exécutée.

Une solution : regrouper les 2 expressions en une seule

En regardant le fonctionnement de l’expression Jscript, une solution simple se dessine. La syntaxe JavaScript utilisée étant du type "condition ? alors : sinon", je vais donc dire à IE :

  • si la taille de l’élément body dépasse une limite de 950 pixels (valeur choisie dans mon exemple pour la propriété CSS max-width),
  • alors : fixer la largeur de div#page à cette valeur maximale de 950px,
  • sinon : fixer la largeur de div#page à la valeur minimale de 740px (valeur choisie dans mon exemple pour la propriété CSS min-width, cette valeur "en dur" se substituant ici à la mention "auto" proposée par Sven Tofte).

Soit :


width:expression(document.body.clientWidth > 950  ? "950px" : "740px" );

En fait, je pose un compromis : sous IE, la largeur de div#page correspondra soit à la valeur définie comme min-width (ici 740 pixels), soit à la valeur en pixels définie comme max-width (ici 950 pixels). Entre ces 2 limites, IE n’évolue pas progressivement, il bascule brusquement d’une largeur à l’autre lorsque j’agrandis ma fernêtre (ou lorsque je la réduis et demande de recharger la page).

Malgré ce petit inconvénient, cette solution semble vraiment intéressante dans le contexte évoqué plus haut, marqué par la variété croissante des définitions (et donc des largeurs) des écrans utilisés par les internautes.

Quelques précisions complémentaires

L’instruction utilisée étant propriétaire, il est souhaitable de l’appeler depuis un commentaire conditionnel.

Par exemple, dans la section "head" de sa page HTML, on trouvera quelque chose comme :


<!--[if IE]>
<style type="text/css" media="screen">
body {
 text-align: center;
}
#page {
   text-align: left;
   width:expression(document.body.clientWidth > 950  ? "950px" : "740px" );
}
</style>
<![endif]-->

Vous noterez que j’ai limité l’effet de cette propriété au "media écran", de manière à ne pas perturber l’impression (pour la même raison, j’ai placé à cet endroit la mention text-align : center ; nécessaire à IE 5/win pour centrer div#page). Dans la même perspective, une feuille de style d’impression (non indiquée ci-dessous) pourrait contenir la règle : #page margin : 0 ; afin que la valeur auto, appliquée ici aux marges gauche et droite, ne perturbe pas l’impression par ce "grand dadais" d’IE.

Récapitulatif du code utilisé


<style type="text/css">
body {
 text-align: left;
}
#page {
   margin: 0 auto;  /* zéro ou une autre valeure */
   width: 100%;
   max-width: 950px;
   min-width: 740px;
   }
</style>

<!--[if IE]>
<style type="text/css" media="screen">
body {
 text-align: center;
}
#page {
width:expression(document.body.clientWidth > 950  ? "950px" : "740px" );
}
</style>
<![endif]-->

Dieu vous bénisse !

[1] "For scripting, a dynamic property can be any legal JScript or Microsoft Visual Basic Scripting Edition (VBScript) statement"

[2] attention, si vous appliquez cette propriété a un autre élément, il importe de s’assurer que la propriété, elle aussi totalement spécifique, haslayout correspondante est positionnée à "true", sinon clientWidth retournera une valeur nulle, comme indiquée sur l’article on having layout traduit et annoté ici Avoir le layout - Le concept de hasLayout dans IE/Win Dès lors, l’élément considéré aura toujours la largeur minimale. Ici, le problème ne se pose pas, "BODY, IMG, INPUT, TABLE and TD elements always have layout".