Reconnaissance de navigateur en pur (X)HTML
Par Gabriel Kerneis le vendredi 27 octobre 2006, 00:42 - Savoirs - Lien permanent
Un billet pour les geeks webmasters soucieux des standards.
Vous avez un site web. Avec une jolie CSS. Mais ce merveilleux navigateur qu'est Internet Explorer ne la gère pas correctement. Sauf, peut-être, la version 7. Or vous n'avez pas envie d'utiliser des hacks ignobles pour corriger les bugs. Vous voulez rester conforme aux standards du W3C. Vous aimeriez juste pouvoir filer à IE une feuille de style dédiée, avec un design simplifié qu'il sache gérer.
La solution : les conditional comments (soit commentaires conditionnels, en français).
Qu'est-ce que c'est ? Ce sont des balises reconnues par IE (uniquement) qui permettent d'afficher ou de révéler du contenu selon la version du navigateur. Il y en a de deux types :
- Les downlevel-hidden conditional comments, qui révèlent le contenu seulement à IE. Ce sont des commentaires au sens classique, ils sont valides (au sens du W3C). Un petit bout de code spécial indique juste à IE qu'il doit afficher le commentaire, et non pas l'ignorer. Concrètement, ça se présente comme ça :
<!--[if lt IE 7]>
Ce texte n'est affiché que par IE, version strictement inférieure à 7 (lt =
lower than).
<![endif]-->
- Les downlevel-revealed conditional comments, qui cachent le contenu seulement à IE. Ce ne sont pas des commentaires au sens classique, ils ne sont pas valides (au sens du W3C). Ce sont des balises supplémentaires, non reconnues par le W3C :
<![if !IE]>
Ce texte est affiché par tout le monde sauf IE.
<![endif]>
Heureusement il y a une solution pour rendre de tels commentaires conditionnels révélés conformes. Ou plutôt, des solutions. Naturellement, la meilleure est tout à la fin (mais il y a de jolies choses à voir avant, qui valent la peine d'être lues).
- Si vous voulez vous contenter d'une détection binaire IE / !IE, alors voilà une méthode simple et efficace :
<!--[if !IE]>-->
Caché pour IE.
<!--<![endif]-->
L'astuce : on utilise un commentaire du premier type (donc standard) et
on dit à IE de l'ignorer totalement, quelle que soit sa version
(!IE). Ensuite, IE va tout ignorer jusqu'au
<![endif]-->. En particulier, nous pouvons à loisir fermer
le commentaire initial, donc rendre la suite visible pour les autres
navigateurs, puis le rouvrir pour mettre le
<![endif]-->.
Si vous voulez affiner en fonction de la version d'IE, ça ne suffit plus. En
effet, si l'on met if IE 7 à la place de if !IE par
exemple, IE 7 va lire la suite et affichera donc : --> Caché pour
IE.<!--. Il nous faut un moyen de lui dire d'ignorer ces bouts de
balise ! Là encore, plusieurs solutions :
- Une méthode de toute beauté (mais qui vous donnera un avertissement de la part du validateur du W3C, car elle est assez osée) :
<!--[if gte IE 7]><!-- -- -->
Caché pour IE<7, visible pour tous les autres.
<!--<![endif]-->
Si vous êtes curieux, voilà quelques détails sur la syntaxe des commentaires en sgml qui devraient vous permettre de comprendre le pourquoi du comment de cette méthode. À noter que si IE7 est vraiment strict (ce que je n'ai pas testé), il vous jettera violemment pour non respect de la syntaxe des commentaires[1].
<!--[if gte IE 7]> <-->
Caché pour IE<7, visible pour tous les autres.
<!--> <![endif]-->
L'usage de cette méthode est en fait déconseillé, elle pose
exactement le même problème que celui qu'elle tente de résoudre :
IE7 affichera le <--> indésirable.
- Ma méthode à moi (en fait antérieurement trouvée par quelqu'un d'autre), qui consiste à cacher les commentaires révélés à l'intérieur de commentaires cachés (IE interprétant les commentaires conditionnels récursivement, même si cela n'est pas explicitement précisé dans la documentation) :
<!--[if IE]>
<![if gte IE 7]>
<![endif]-->
Caché pour IE<7, visible pour tous les autres.
<!--[if IE]>
<![endif]>
<![endif]-->
C'est la méthode que je recommande : elle fonctionne et est valide en toutes circonstances (sauf si Microsoft décide que les commentaires conditionnels ne doivent plus être interprétés récursivement).
Un exemple d'application ? Tiré du lien précédent :
<!--[if IE]>
<link rel="stylesheet" href="ie.css" type="text/css" />
<![if !IE]><![endif]-->
<link rel="stylesheet" href="others.css" type="text/css" />
<!--[if IE]><![endif]><![endif]-->
Ainsi, la feuille de style ie.css est lue par IE,
others.css par les autres navigateurs. Si l'on veut distinguer
selon IE7, c'est un peu plus touffu, mais toujours le même principe :
<!--[if IE]>
<![if gte IE 7]>
<![endif]-->
<link rel="stylesheet" href="ie7-and-others.css" type="text/css" />
<!--[if IE]>
<![endif]>
<![endif]-->
<!--[if lt IE 7]>
<link rel="stylesheet" href="ie-lt-7.css" type="text/css" />
<![endif]-->
Quelques ultimes détails :
- Certains n'aiment pas rajouter du code dans leur page pour gérer l'apparence. C'est compréhensible, au nom de la séparation du fond et de la forme. Si vous en faites partie, vous serez peut-être intéressés par une solution en pur CSS (c'est un hack, mais plutôt résistant).
- Les commentaires conditionnels ne sont pas forcément la panacée : un article à ce sujet.
- Vous pouvez aussi mettre une feuille de style visible pour vraiment tout le monde et ensuite rajouter un commentaire caché juste pour IE, avec des directives supplémentaires, pour compléter/corriger ce qu'il interprète mal dans la première feuille. Ça évite la duplication de code entre vos deux feuilles de style.
Notes
[1] C'est en particulier possible si vous servez vos pages en tant que xml au niveau du serveur web, ce qui est rarement le cas.


Commentaires
C'est bon j'ai trouver il faut utiliser cette syntaxe:
<xsl:comment><!CDATA[[if IE><link rel="stylesheet" type="text/css" href="style/ie.css" /><!endif]]></xsl:comment>
Cdt,
Philippe
C'est bon j'ai trouver il faut utiliser cette syntaxe:
<xsl:comment><!CDATA[[if IE><link rel="stylesheet" type="text/css" href="style/ie.css" /><!endif]]></xsl:comment>
Cdt,
Philippe