Obtenir la transparence PNG avec Internet Explorer 6

Astuce par Florent V. (Chef de projet, intégrateur web, Lyon, France)
Mis à jour le 07 Février 2009 à 13h25. 9987 lectures.
Tags : design, webdesign, IE6, alpha, directx, transparence, png

Le format d'images PNG (et plus particulièrement le PNG32) permet de gérer des images RVB dotées d'une couche alpha, c'est à dire d'indications de transparence graduelle. Contrairement au format GIF et à son équivalent, le PNG8, il ne s'agit pas d'une transparence binaire (un pixel est soit transparent, soit opaque), mais bien d'une transparence graduelle: chaque pixel peut être un peu, beaucoup ou pas du tout transparent (256 nuances).

C'est donc un format très pratique pour le design web. Sauf que... le navigateur Internet Explorer est réputé pour ne pas supporter la transparence PNG, et afficher les images PNG transparentes avec un fond gris opaque particulièrement laid.

Il est faux de dire qu'Internet Explorer ne supporte pas la transparence PNG. La version 7 de ce navigateur l'interprète aussi bien que tous les autres navigateurs modernes. Par contre, c'est effectivement le cas pour la version 6, encore très largement utilisée, et sur laquelle il faudra compter pour quelques temps encore.

Il existe toutefois un moyen détourné d'obtenir «plus ou moins» du PNG transparent avec Internet Explorer 5.5 et 6.0, que nous allons détailler.

Les filtres Alphaimageloader

À partir de la version 5.5, Internet Explorer intègre le support de fonctions propriétaires permettant de faire appel à DirectX pour certaines manipulations graphiques. L'une de ces manipulations graphiques consiste à intercaler, entre le fond d'un bloc et son contenu, une image avec transparence graduelle.

On peut utiliser cette fonctionnalité via Javascript, mais nous passerons ici par la propriété CSS non standard "filter". Afin d'éviter que cette propriété ne s'applique à IE7 également, et pour garder un code CSS valide par ailleurs, on utilisera un commentaire conditionnel:


<!-- Code à insérer dans le "head" de la page -->
<!--[if lte IE 6]>
<style type="text/css" media="screen">
#bloc {
background: none; /* Il supprimer l'image de fond s'il y en a une de déclarée dans la feuille de styles principale */
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="/chemin/vers/mon-image.png", sizingMethod="scale");
}
</style>
<![endif]-->

Attention, si on place cette propriété dans une feuille de styles externes (une feuille de correctifs CSS pour IE6 et inférieurs appelée via un commentaire conditionnel, par exemple), le chemin ne s'appliquera pas depuis la feuille de style (comme c'est normalement le cas en CSS), mais depuis la page HTML. Une solution pour ne pas s'emmêler les pinceaux: utiliser des chemins absolus, commençant par "/".

Le code ci-dessus permet donc d'afficher l'image PNG, qui sera étirée (sizingMethod="scale") dans le bloc. Les valeurs possibles pour la propriété sizingMethod sont:

  • "crop" (rogne l'image pour qu'elle tienne dans le bloc);
  • "image", valeur par défaut (réduit ou élargit le bloc pour correspondre aux dimmensions de l'image);
  • "scale" (étire l'image aux dimmensions du bloc).

Les limites de cette méthode

Tout d'abord, il faut bien noter que le filtre AlphaImageLoader ne substitue pas une image (avec transparence PNG activée) à l'image de fond d'un bloc. L'image placée en «fond» du bloc (en fait entre le fond et le contenu) n'est pas une image de fond à proprement parler, et on ne pourra pas utiliser les propriétés CSS pour les images de fond.

Donc:

1. pas de background-position (et pas d'équivalent via des propriétés d'AlphaImageLoader);

2. pas de background-repeat (et pas d'équivalent... sauf peut-être sizingMethod="scale" pour les images unies, sans motif, et dans les cas où on aurait pu utiliser une image de fond de 1px de haut répétée en hauteur -- ou une image de 1px de large répétée en largeur).

Une autre limite importante vient du fait que pour que cela fonctionne, le bloc doit avoir le LAYOUT. Il faudra donc peut-être également conférer le "layout" au bloc, par exemple de la manière suivante:


<!--[if lte IE 6]>
<style type="text/css" media="screen">
#bloc {
zoom: 1; /* HasLayout */
background: none;
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="/chemin/vers/mon-image.png", sizingMethod="scale");
}
</style>
<![endif]-->

Au sujet du HasLayout, on pourra lire:

L’étrange HasLayout de Monsieur Internet Explorer

Effets secondaires du filtre Alphaimageloader

Le filtre AlphaImageLoader a plusieurs effets secondaires. Le principal est que le texte à l'intérieur d'un élément sur lequel on a appliqué le filtre n'est plus sélectionnable, les liens plus cliquables, etc. Cela se corrige le plus souvent en passant le texte ou les liens en positionnement relatif. Mais cela peut être un peu plus subtil et il y a des cas particuliers assez retors, comme par exemple quand l'élément sur lequel on utilise le filtre est positionné en absolu.
Cf. http://web.covertprestige.info/test/47-alphaimageloader-absolute.html

On pourra aussi lire (en anglais) :
http://www.satzansatz.de/cssd/tmp/alphatransparency.html

Enfin, il faut noter que l'utilisation du filtre AlphaImageLoader n'est pas neutre en termes de performances. D'aucuns conseillent de ne pas l'utiliser :
http://performance.survol.fr/2008/07/ne-pas-filtrer-les-pngs/

Automatiser l'utilisation de Alphaimageloader avec JavaScript

Plusieurs scripts Javascript se proposent d'appliquer automatiquement les correctifs nécessaires à la prise en compte de la transparence PNG dans IE6, soit pour les images dans le code HTML, soit pour les images de fond CSS, soit pour les deux.

Celui-ci est régulièrement cité (nota: explications en anglais) :
http://www.twinhelix.com/css/iepngfix/

Ressources