Parmi les nombreux bugs qui affectent Internet Explorer 6, le bug des classes multiples apparait lorsqu’on utilise au moins deux classes CSS simultanément. Par exemple `.classe1.classe2` pour adresser des propriétés CSS aux éléments possédant à la fois `.classe1` et `.classe2`, ce qui est très pratique. Malheureusement, IE6 ne tient compte que de la dernière classe, soit `.classe2`, en l’occurrence. Une pratique répandue consiste simplement à se passer des classes multiples, ce que je fais depuis des années.
Malgré des débuts prometteurs, en 10 ans de bons et loyaux services sévices, Internet Explorer 6 ne s’est pas fait que des amis… [Illustration ci-contre par Mike Rohde]
Toutefois, il se trouve que dans le cadre d’un projet utilisant WordPress, j’avais besoin de styler différemment les images selon qu’elles possèdent une légende ou pas, qu’elles soient alignées à droite, à gauche, au centre, pas du tout (à la folie, passionnément, etc.) et selon leur taille. Ce qui donne un nombre de combinaisons suffisamment important pour justifier l’utilisation des classes multiples, y compris dans IE6. En effet, dans mon cas, l’alignement des images fait partie intégrante du design qui doit (Must vs. Should) passer aussi dans IE6. Et non, en l’occurrence, le script kickie6.js n’est pas envisageable 😀
Dans l’idéal, il faudrait une fonction Javascript pour détecter les classes multiples passées en paramètres afin d’obtenir en retour la concaténation des deux classes séparée par un tiret (ex. `.classe1-classe2`. N’étant pas développeur Javascript, j’ai fais appel aux bonnes volontés présentes sur Twitter. Quelques heures plus tard, plusieurs propositions surgirent.
Petit mais costaud, c’est jQuery
Quand on joue sur le web, jQuery est souvent de la partie. Il devient assez rare de faire l’économie d’un framework Javascript, quel qu’il soit. Voici deux méthodes pour ajouter une classe CSS afin de pallier les insuffisances d’Internet Explorer 6 en matière de gestion des classes multiples.
- La solution fournie par Florian (@_Florian_R) a le mérite de la simplicité et de l’efficacité. Il suffit de passer les classes multiples à la fonction `jQuery()` et d’ajouter la classe de son choix avec la méthode `addClass()`. Seul petit bémol, cette méthode oblige à parcourir tout le document à la recherche des deux classes.
$(document).ready(function() { $(".classe1.classe2").addClass("classe1-classe2"); });
- Allons plus loin avec Stéphane Rouillé (@stfr) — Web Developper, PHP and jQuery addict. Sa fonction permet, au choix, de remplacer les deux classes précédemment utilisées par une nouvelle classe (replace : true;) ou de les garder (replace : false;). Il est possible de spécifier le noeud DOM pour éviter de parcourir l’ensemble du document afin de ne pas gréver inutilement les performances déjà limitées de notre très cher (coûteux) IE6 !
/* * Merge multiple CSS classes in one. * Just use : $('body').multipleClassCombiner(); in order to apply this filter on all multiple classes elements * Take care : $('h1').multipleClassCombiner() will apply this filter on <h1>'s childrens. But you can easily modify it. * Default delimiter : "-" * Have Fun ! * @author Stéphane Rouillé (Twitter: @stfr) * @date 2011-02-08 * Free to use, distribute, modify, etc etc... */ (function($) { $.fn.multipleClassCombiner=function(params){ var options={ delimiter:'-', replace : true }; $.extend(options,params); var multipleClassElements=$(this).find("*[class*=' ']"); /* Oh god ! */ multipleClassElements.each(function(){ var classes=$(this).attr('class').trim().split(' '); if(options.replace){ $(this).attr('class',classes.join(options.delimiter)); }else{ $(this).attr('class',$(this).attr('class')+' '+classes.join(options.delimiter)); } }); } })(jQuery);
Regarde Maman, sans jQuery !
jQuery est souvent une bonne idée, mais de nombreux projets de sites internet ne nécessitent pas de framework. Mettre en place jQuery *juste* pour gérer les classes multiples dans IE6 n’est pas très raisonnable : les utilisateurs de ce navigateur obsolète utilisent déjà des configurations assez modestes… Inutile, donc, de charger la mule 😉
C’est Edouard Cunibil (@DuaelFr) — Développeur web freelance certifié PHP — qui nous offre une fonction en pur Javascript. Pour utiliser `patchMultipleClass()`, il suffit de passer les classes multiples en paramètres, en ajoutant, le cas échéant, le noeud DOM impliqué dans la recherche. Par défaut, la fonction parcours tout le DOM à partir de `body`, mais rien ne vous empêche de limiter les dégâts à `#content`, par exemple.
function patchMultipleClass(classNames, parent) { var children, current, classes, found, subfound, splitClassNames, joinClassNames; var i, j, k; splitClassNames = classNames.substr(1).split('.'); joinClassNames = splitClassNames.join('-'); if (!parent) { parent = document.getElementsByTagName('body')[0]; } children = parent.children; for (i = 0 ; i < children.length ; ++i) { current = children[i]; classes = current.className.split(' '); found = true; for (j = 0 ; j < splitClassNames.length ; ++j) { subfound = false; for (k = 0 ; k < classes.length ; ++k) { if (classes[k] == splitClassNames[j]) { subfound = true; break; } } if (!subfound) { found = false; break; } } if (found) { if (current.className.indexOf(joinClassNames) == -1) { current.className += ' ' + joinClassNames; } } patchMultipleClass(classNames, current); } } if (window.attachEvent) { window.attachEvent("onload", function() { var parentElt = document.getElementById('content'); patchMultipleClass('.wp-caption.alignright', parentElt); patchMultipleClass('.wp-caption.alignleft', parentElt); patchMultipleClass('.wp-caption.alignnone', parentElt); patchMultipleClass('.wp-caption.aligncenter', parentElt); }); }
Cibler uniquement IE6
Pour réserver ce traitement Javascript aux seuls navigateurs ne prenant pas en charge les classes multiples (IE5 — IE6), j’utilise les commentaires conditionnels :
<!--[if lte IE 6]> <script src="<?php bloginfo( 'stylesheet_directory' ); ?>/js/functions-ie6.js""></script> <![endif]-->
Voilà, c’est fini !
J’espère que ces quelques précisions sur ces quelques fonctions Javascript permettant de gérer les classes multiples dans Internet Explorer 6 vous permettront de vous amuser. Je tiens une nouvelle fois à remercier Florian (@_Florian_R), Stéphane Rouillé (@stfr) et Edouard Cunibil (@DuaelFr) pour avoir planché nuitamment sur ce problème 🙂
N’hésitez pas à partager vos découvertes sur ce sujet, elles seront les bienvenues.
Merci également à tous ceux qui ont répondu d’une manière ou d’une autre à l’appel : @mgeoffray, @Remzz, @Tchesssss, @JeuneVeteran, @phenxdesign, @burninghat, @jcbrebion, @Darklg, @LDZintegratore, @naholyr, @piouPiouM, @cafenoirdesign, @rickdog, @studiohypehope.
Retrouvez-moi sur Twitter avec @br1o !
Juste un petit détail concernant ma fonction : le second paramètre doit être un noeud du DOM donc le #content ne fonctionnera pas (surtout sans jQuery).
Remplace le donc par un document.getElementById(‘content’) mis dans une variable histoire d’économiser les 4 appels que tu en fais.
Si besoin du même paramétrage que sur la fonction de @stfr ça peut s’arranger aussi 😉
Arf, j’ai voulu aller trop vite : la fougue de la jeunesse ^__^v. Je suis preneur de toutes les améliorations 😉
Et ça continue 😉
Allez je te passe le snippet sinon tu t’en sortiras pas !
if (window.attachEvent) {
window.attachEvent(« onload », function() {
var parentElt = document.getElementById(‘content’);
patchMultipleClass(‘.wp-caption.alignright’, parentElt);
patchMultipleClass(‘.wp-caption.alignleft’, parentElt);
patchMultipleClass(‘.wp-caption.alignnone’, parentElt);
patchMultipleClass(‘.wp-caption.aligncenter’, parentElt);
});
}
Alala, merci beaucoup de me prendre par la main. Hop, comme ça c’est nickel 🙂
A noter que mon plugin jQuery est une machine de guerre qui sur des sites complexes risque de ralentir légèrement la génération. Il faudrait par ailleurs limiter son application qu’à IE6, je le rajouterais prochainement.
L’idéal est toujours de se passer de tricks JS de ce genre, même si ces fonctions font leur job et rendent service si besoin ! 😉
Merci pour cette précision. J’ai ajouté l’utilisation des commentaires conditionnels pour les navigateurs < ou = à IE6
Pour info, le attachEvent que j’ai utilisé ne fonctionne que sous IE mais toutes versions confondues par contre :/
Pour info, le attachEvent que j’ai utilisé ne fonctionne que sous IE mais toutes versions confondues par contre :/
Coquille: « ne c’est pas fait que des amis… » => « ne s’est pas fait que des amis… » 🙂
Bonjour Bruno,
Je m’en vais tester tes lumières, merci pour ce partage. Ha ,si seulement on pouvait jeter cet IE6 aux oubliettes !
Bonjour et merci à tous. Cela reste une galère considérable dans mon cas, les classes multiples, les hover, les png. Si je dois prendre IE6 en considération, il va passer une heure à charger tous les scripts nécessaires à une représentation, je vais dire passable, de ma page. Pire, j’utilise du CSS3… Avec 3,68% de lecteurs en IE6 le mois dernier, je me demande si cela vaut le coup. Enfin, dans tous les cas, c’est intéressant de savoir qu’il existe malgré tout une solution.
Belle journée.
Thierry
Je dirais que le client qui insiste pour qu’une image soit alignée comme il faut sous un navigateur en voie de disparition n’a rien compris et j’espère que tu lui as facturé le prix fort correspondant à la recherche d’une « solution ».
Je déteste presque plus l’utilisation de solutions js qui servent à faire du cosmétique qu’IE6 lui même! vive l’amélioration progressive.
ps si je ne m’abuse ce sélecteur
.wp-caption.alignright .size-thumbnail {}
peut être remplacé par :
div.alignright .size-thumbnail {}
Oui, effectivement dans ce cas, on peut utiliser cette solution, merci 🙂
Pour ce qui est de « facturer » le prix fort, je dirais que si c’était le cas, il faudrait que je reverse cette somme à ceux qui ont créé les fonctions au final ^^
Mouahahaha ! ben moi je dis, que ceux qui utilisent IE6 aillent se faire empapaouter par un ours … 5% des visiteurs … eh bien tant pis pour eux… ça fait 300 heures de boulot de gagnées pour moi
… ou 300 heures de facturation en moins 😀