Accueil > Articles
Mis à jour le 7 février 2006.
Les commentaires conditionnels sont de plus en plus souvent utilisés comme substituts aux hacks CSS afin de gérer les défauts d'implémentation CSS d'IE 5.x et 6.0 Windows. Leur usage est également préconisé par Microsoft en prévision des changements apportés par IE7. Voici un rappel des différentes possibilités offertes par ces commentaires et des syntaxes à utiliser dans le contexte de documents HTML et XHTML1.0 traités en tant que text/html.
Sommaire
Les commentaires conditionnels sont un mécanisme propre à Internet Explorer Windows depuis sa version 5.0. Ils ne sont donc transposables à aucun autre navigateur (Opera, Safari, Firefox...) et n'ont pas d'effet sur Internet Explorer 5 Mac.
Ils permettent :
text/html)
La documentation MSDN (Microsoft) différencie deux types de commentaires conditionnels, dont un seul cependant est valide en HTML :
La syntaxe de base d'un commentaire conditionnel Downlevel-hidden est :
<!--[if IE]> ..ici, code HTML réservé à IE... <![endif]-->
Leur principe est :
<!-- : à partir de ce point, le balisage HTML n'est plus interprété comme tel par les navigateurs autres qu'IE Windows. Pour eux, tout ce qui va suivre, jusqu'au --> de la dernière ligne, est un commentaire HTML comme un autre.
[if IE] (et ses variantes) qui va être lue et interprétée par IE Windows.
> : en l'absence de double tiret --, il ne ferme pas le commentaire HTML pour les navigateurs autres qu'IE Windows. Pour ce dernier, en revanche, il indique que ce qui suit devra être interprété en tant que HTML
<![endif]. Il indique à celui-ci que le contenu conditionnel est terminé. Le <!, en revanche, n'est pas interprété par les autres navigateurs, pour qui nous sommes toujours dans le cadre d'un commentaire.
-->. Le double tiret indique aux navigateurs que le chevron qui suit signale la fin du commentaire.
Le commentaire conditionnel peut viser une ou plusieurs versions d'IE Windows, selon une syntaxe simple :
if IE est la condition générique minimale, signifiant toutes les versions d'IE
if IE 5 visera IE5.0 et IE5.5
if IE 6 ne visera qu'IE6.0
if IE 7.0b ne visera que la pre-beta 2 d'IE7.0 (par la suite, if IE 7 ne visera qu'IE7.0)
if IE 5.0 et if IE 5.5. En revanche, pour viser une version très précise d'IE, il est nécessaire de préciser la totalité du numéro de version : 5.5000 pour la première version d'IE5.5, par exemple.
Il est également possible d'utiliser des opérateurs de comparaison sur les numéros de version :
lt pour strictement inférieur à (less than): le contenu d'un commentaire if lt IE 6 ne sera lu que par IE5.0 et IE5.5
lte pour inférieur ou égal à : le contenu d'un commentaire if lte IE 6 sera lu par IE6.0, IE5.5 et IE5.0
gt pour strictement supérieur à (greater than): le contenu d'un commentaire if gt IE 6 ne sera lu que par IE7 (et au-delà)
gte pour supérieur ou égal à : le contenu d'un commentaire if gte IE 6 sera lu par IE6.0 et IE7.0 (et au-delà)
On pourra donc utiliser ces commentaires conditionnels pour:
Le code placé dans la section head du document (X)HTML sera du type :
<link href="all-browsers.css" rel="stylesheet" type="text/css" /> <!--[if lte IE 6]> <link href="ie-only.css" rel="stylesheet" type="text/css" /> <![endif]-->
On peut tout aussi bien utiliser les règles @import pour la feuille conforme, afin de filtrer les navigateurs de génération 4 ou IEMac, ou encore gérer des styles alternatifs en dehors d'IE Windows. Le link utilisé dans le commentaire conditionnel, lui, n'aura pas à être modifié.
Le commentaire conditionnel peut également contenir un élément style avec des styles internes, ou une règle @import, etc. (comme n'importe quel autre élément HTML).
La feuille de style corrective pourra être limitée au strict minimum, et n'aura pas à reprendre l'intégralité des styles de la feuille conforme : si les mêmes sélecteurs CSS sont utilisés, le jeu de la cascade suffira pour qu'IE modifie la feuille conforme en fonction des propriétés de la feuille corrective.
Par exemple, si une règle #foo {position: fixed} pose un problème et doit être modifiée pour IE5.x-6.0 (pas de support de la position fixe), la seconde feuille de style la réécrira simplement avec la valeur qui convient pour celui-ci: #foo {position: absolute}.
De la même manière, on pourra ajouter via cette feuille conditionnelle des propriétés supplémentaires, corrigeant tel ou tel bug CSS d'IE. Par exemple :
#foo {display:inline} pour compenser dans IE5.x-6.0 un bug de double marge d'un flottant #foo {float:left; margin-left:50px:}
#foo{height: 1%;} pour compenser dans IE5.x-6.0 l'un des bugs liés au haslayout
A l'aide des sélecteurs de version, on pourra adresser des correctifs différents à IE6.0, IE5.5 et IE5.0 (en attendant IE7). Dans la pratique, il s'agira surtout de différencier IE5.0 d'une part et IE5.5-6.0, le premier ayant souvent besoin de correctifs supplémentaires :
<!--[if lte IE 6]> <link rel="stylesheet" type="text/css" href="ie50-60-win.css" /> <![endif]--> <!--[if lt IE 5.5000]> <link rel="stylesheet" type="text/css" href="ie50-win.css" /> <![endif]-->
Ici, la première feuille contient les correctifs communs aux trois versions IE6.0, 5.5 et 5.0. La seconde contient les correctifs réservés au seul IE5.0, qui seraient problématiques pour les deux précédents. On aurait pu utiliser pour cette seconde feuille la syntaxe <!--[if IE 5.0]>, qui aurait été a priori plus directe. Mais il semble, à l'usage, qu'elle ne soit pas correctement reconnu comme attendu par toutes les versions d'IE 5.0 (indépendamment des problèmes de support des commentaires conditionnels dans les versions standalone d'Internet Explorer). Je n'ai pas eu la possibilité, lorsque j'ai rencontré ce problème, d'approfondir et de déterminer la source exacte de l'erreur. En tout état de cause, la synthaxe <!--[if lt IE 5.5000]> (c'est à dire tout ce qui est strictement inférieur à la première version d'IE5.5) a produit le resultat escompté.
Jusqu'ici, nous avons réservé une feuille de style à Internet Explorer. Dans certains cas, on peut cependant souhaiter au contraire masquer une feuille de style à IE Windows globalement, ou à l'une de ses versions en particulier. Ceci peut également concerner d'autres éléments de code HTML en dehors des liens de feuilles de style.
Il existe plusieurs syntaxes de liaisons link ou @import qui jouent sur les défauts d'implémentation d'IE pour lui masquer une feuille de style. Par exemple :
<link type="text/css; charset=utf-8" rel="stylesheet"... />
La mention (parfaitement conforme) du charset dans le type de contenu de l'élément link empêche toutes les versions connues d'IE, windows et Mac, de reconnaître la feuille de style. Ce comportement est reproduit par les versions bêta 1 et pre-bêta 2 d'IE7.
Autre exemple, pour que la feuille de style ne soit pas lue par IE5.0 Windows et Mac, ni par les navigateurs de génération 4, mais soit lue par IE5.5 Windows et au-delà, et bien-sûr, par les navigateurs conformes :
<style type="text/css" media="screen"> @import'style.css'; </style>
On joue ici sur l'absence du mot url, qui est optionnel dans la valeur de @import.
Mais il est également possible de jouer sur les commentaires conditionnels, de manière valide, en exploitant les possibilités offertes par la syntaxe des commentaires HTML, ainsi que l'a proposé Yan Hixon à propos de Flash. Ceci constitue, notons-le, un détournement des commentaires conditionels Downlevel-hidden pour contourner l'invalidité HTML des commentaires Downlevel-revealed.
Pour masquer une feuille de style (ou un autre code HTML) à toutes les versions d'IE Windows, on écrira:
<!--[if !IE]> <--> <link href="all-browsers-not-ie-win.css" rel="stylesheet" type="text/css" /> <!--> <![endif]-->
On voit ici apparaître l'opérateur de négation ! (not). L'expression if !IE signifie simplement Si le navigateur n'est pas IE Windows.
Surtout, on remarque également l'apparition de balisages de commentaires HTML supplémentaires. Le principe est :
<!--[if !IE]>, si ce n'est pour la condition not IE dans notre exemple. Celui-ci va donc ignorer tout ce qui suit jusqu'au [endif]. D'autres conditions, incluant ou non la négation, peuvent être utilisées.
<--> : le double tiret indique aux navigateurs que le chevron > qui suit est une fermeture de commentaires HTML. La ligne suivante est donc interprétée par Safari, Opera, Firefox (et Internet Explorer Mac), etc. comme un lien tout à fait habituel vers une feuille de style.
link vers la CSS (ou l'élément style équivalent).
<!--> indique la réouverture d'un nouveau commentaire HTML
<![endif]
-->.
L'intérêt de cette technique est cependant de pouvoir viser, à nouveau, telle ou telle version d'IE Windows, en jouant sur les conditions et les numéros de version. Par exemple:
<!--[if IE 7]> <--> <link rel="stylesheet" href="modern-browers.css" type="text/css" /> <!--> <![endif]--> <!--[if lte IE 6]> <link rel="stylesheet" href="old-ie.css" type="text/css" /> <![endif]-->
La première feuille de style:
[if IE 7]
La seconde feuille de style ne sera, à l'inverse, lue que par IE5.x et 6.0 Windows...
Selon le même principe, on peut donc différencier totalement les feuilles de styles selon que le navigateur est l'un des navigateurs conformes actuels (Safari, Opera, Firefox, Konqueror), ou bien telle version d'IE, et/ou telle autre.
Les limites de cette démarche, et ses dérives possibles sont cependant évidentes : il ne s'agit pas de revenir à une discrimination systématique des styles CSS selon le navigateur, ce qui ferait perdre en grande partie l'un des atouts de la conformité aux standards, c'est à dire l'interopérabilité d'un même style pour tous les navigateurs et les économies ainsi réalisées. On voit également que ce système peut rapidement devenir complexe et peu maintenable. Enfin, toutes les syntaxes de commentaires conditionnelles ci-dessus sont susceptibles de provoquer des erreurs de parsing dans un document XHTML traité en tant que XML (C'est pourquoi nous avons explicitement restreint cet article au HTML et au XHTML1.0 traité en tant que text/html).
Il s'agit donc d'user de ces commentaires conditionnels avec modération, quand ils permettent de réaliser une économie, et non de diminuer l'efficience de votre démarche.