CSS: Pseudo classes sur Internet Explorer
Grâce aux expressions CSS d’Internet Explorer, il y a moyen de simuler les pseudo-classes qui ne sont pas supportées par IE6.
Les expressions CSS d’Internet Explorer
En effet, les expressions CSS (apparues avec IE5) permettent de calculer dynamiquement (via JScript) les différentes propriétés stylistiques.
On attribue une valeur calculée par JScript à une propriété CSS d’un élément html. Les différents objets du DOM sont supportés
#centeredDiv { position:absolute; left: expression( (document.body.clientWidth/2)- (this.offsetWidth/2) ); top: expression( (document.body.clientHeight/2)- (this.offsetWidth/2) ); }
Sur Internet Explorer, cet exemple positionnerait l’élément ayant un id centeredDiv
au centre de la page en le positionnant à la différence de la moitié hauteur de la page (document.body.clientHeight/2
) et de la moitié de sa hauteur (this.offsetWidth/2
). Notez que this
représente l’objet en lui-même.
Les pseudo-classes :first-child et :last-child sur Internet Explorer
Avant Internet Explorer 7, ces pseudo-classes (propriétées qui ne sont pas issues d’éléments html en eux-mêmes) n’étaient pas supportées. Donc, galère pour les intégrateurs pour produire du code html compatible entre les différents navigateurs.
Grâce aux expressions CSS, ce manque de support des pseudo-classes peut être corrigé.
Pseudo-classe :first-child
sur IE<=6
li { background-image: expression( (this===this.parentNode.childNodes[0]) ?"none":"auto" ); }
Explication du code:
L’élément à styler est les tags LI
. Je définis à l’aide d’une expression CSS la valeur de la propriété background-image
.
Si l’élément en question (le LI
représenté par this
est strictement égal (===
: égalité de la valeur et de type d’élément) au premier enfant (.childNode[0]
) de l’élément parent de l’objet LI
en question (this.parentNode
), la valeur de l’image de fond sera none
.
Dans le cas contraire, l’image de fond sera la valeur par défaut (via héritance) d’un list-item.
Pseudo-classe :last-child
sur IE<=6
li { background-image: expression( (this===this.parentNode.childNodes[this.parentNode.childNodes.length-1]) ?"none":"auto" ); }
Explication du code:
Dans ce cas-ci, je ne vise pas le premier élément de la liste d’enfants de l’élément parent (this.parentNode.childNodes[0]
) mais bien le dernier (this.parentNode.childNodes[this.parentNode.childNodes.length-1]
, l’élément à la dernière position de l’array childNodes
est l’élément ayant la position égale à la longueur de l’array moins un).
Si l’élément en question (le LI
représenté par this
est strictement égal (===
: égalité de la valeur et de type d’élément) au premier enfant (.childNode[0]
) de l’élément parent de l’objet LI
en question (this.parentNode
), la valeur de l’image de fond sera none
.
Dans le cas contraire, l’image de fond sera la valeur par défaut (via héritance) d’un list-item.
Code html et programmation simplifiée.
Maintenant que l’on peut simuler un équivalent des pseudo-classes sur Internet Explorer, le code html (ou la programmation de celui-ci) pourra être simplifié.
Prenons une liste de liens séparés par un élément graphique (une petite barre verticale).
Avant, si on mettait le séparateur vertical en background-image
d’un élément de liste, pour avoir du code html compatible avec autant IE6 et Firefox, il fallait spécifier une classe CSS au premier ou au dernier élément de la liste pour ne pas mettre d’image de fond sur le premier ou dernier élément.
<ul class="fxNav"> <li class="firstChild"><a href="/solutions/index.php">Solutions</a></li> <li><a href="/products/index.php">Produits</a></li> <li><a href="/support/index.php">Support</a></li> <li><a href="/communities/index.php">Communautés</a></li> <li><a href="/company/index.php">Société</a></li> <li><a href="/download/index.php">Télécharger</a></li> <li><a href="/store/index.php">Store</a></li> </ul>
Maintenant grâce à l’équivalent des pseudo-classes CSS sur Internet Explorer, les développeurs peuvent supprimer une condition dans leur code!
<ul class="fxNav"> <li><a href="/solutions/index.php">Solutions</a></li> <li><a href="/products/index.php">Produits</a></li> <li><a href="/support/index.php">Support</a></li> <li><a href="/communities/index.php">Communautés</a></li> <li><a href="/company/index.php">Société</a></li> <li><a href="/download/index.php">Télécharger</a></li> <li><a href="/store/index.php">Store</a></li> </ul>
Le code en pratique.
ul.fxNav, ul.fxNav li { list-style-type:none; margin:0;padding:0; display:inline; } ul.fxNav li { text-transform:uppercase; font-size:1em; padding:0 5px 0 7px; background:url(pipe.gif) no-repeat 0 50%; } ul.fxNav li:first-child { background:none; }
Pour tous les navigateurs, je définis que les éléments LI
ont une image de fond (pipe.gif
). Après cela, je réécris l’instruction pour le premier li
de la liste ayant une class fxNav
.
Ceci marche sur Firefox, Opera, Safari et IE7.
Pour rendre ceci compatible avec les versions précédentes d’Internet Explorer, je rajoute des instructions, propres aux versions concernées d’IE et après les instructions CSS communes, mises dans des commentaires conditionnels pour conserver du code valide.
<!--[if lte IE 6]> <style type="text/css"> ul.fxNav li { background-image: expression( (this===this.parentNode.childNodes[0])? "none":"auto" ); } </style> <![endif]-->
Je mets à votre disposition d’un exemple de pseudo-class :first-child qui fonctionne sur IE <=7. En espérant que ça vous sera utile !
Liens relatifs :
- Démo de navigation avec l’équivalent de pseudo class :first-child
- les expressions CSS d’Internet Explorer
- les définitions des pseudo-classes sur le W3C
- Les commentaires conditionnels d’Internet Explorer
Comments
14 commentaires à “CSS: Pseudo classes sur Internet Explorer”
Laissez un commentaire
Super pratique tout ça !
J’y avais jeté un oeil aussi et j’ai trouvé une bonne façon de simuler max-width sur IE : http://developpeur.journaldunet.com/tutoriel/dht/050427-css-ie-max-width.shtml
Vraiment super pratique les expressions d’Internet Explorer. J’espère qu’une mise à jour ne viendra pas les désactiver 🙂
Enfin, ça reste du javascript, donc dès qu’un visiteur (sous IE) a le malheur d’avoir javascript désactivé il risque d’avoir le design totalement détruit.
Donc à utiliser avec prudence.
Un autre sélecteur qui n’existe pas sur IE: le “adjacent selector”
Les vrais navigateurs comprennent:
h3+h4 {
background-color:#FC0
}
qui veut dire qu’un H4 précédé d’un H3 aura une couleur jaune. Evidemment ça ne marche pas sous IE6.
Pour corriger ceci: voici le code:
<!--[if lte IE 6]>
<style type="text/css">
h4 {
background-color:expression((this.previousSibling.tagName=="H3")?"#FC0":"auto");
}
</style>
<![endif]-->
@Country: en effet, les expressions ne passent pas avec javascript désactivé. Il faut effectivement utiliser avec modération. Ou alors migrer vers un navigateur qui supporte mieux les standards css que les anciennes versions de IE.
Genial, genial! Je n’entends sur ces ‘behaviours’ IE que rarement, qui fait que je n’en avais pas grande confiance… Mais quand on me presente une technique complete comme celle-si, et de plus que ca soit bien explique, ca fait toute la difference.
Merci bien.
Marin:
Mise a jour?! Produit Microsoft?!? T’inquiete, ca viendra pas ce siecle!
Kéé GEEEEEEEEEEEK quoi!
Je viens de tomber là-dessus : Avoid CSS Expressions
http://developer.yahoo.com/performance/rules.html#css_expressions
Yep Ced, j’ai vu que les expressions étaient interprétées plus qu’une seule fois au chargement de la page. Je vais investiguer sur “the first time the expression is evaluated it sets the style property to an explicit value”.
[…] si vous préférez cette dernière méthode vous pouvez voir de quoi il retourner sur le JDN ou sur Gatellier.be (perso je préfère faire le max en CSS sir c’est […]
[…] avec IE <=6 > Mais si, il suffit de terminer le d
Je trouve que ces expressions css tuent la vache.
Radicalement.
C’est étrange je n’ai réussit à le faire fonctionner qu’en mettant :
expression((this === this.parentNode.childNodes[1])?
pourtant je n’ai qu’une qui englobe des …
En fait c’était du au fait qu’ie6 interprète aussi les commentaires comme une vraie balise.