CSS: Domptez IE (Et les autres…)
Posté par jbj le 6 août 2007 dans (x)HTML/CSS • 6 commentairesToute personne s'étant déjà essayée aux joies des css et des standards web sait à quel point les problèmes potentiels sont nombreux. On à beau respecter à la lettre les recommandations du W3C, Internet Explorer (particulièrement les versions 6 et inférieures) à trop souvent un comportements étrange.
Pour cela, les développeurs et intégrateurs ont inventé diverses techniques, nommées hacks et qui ont pour but de modifier le comportement d'un ou plusieurs navigateur afin de lui faire prendre en compte une propriété, ou encore de corriger certains bugs.
Les hacks que vous trouverez ici sont de qualité diverses: Si certains sont recommandés, d'autres ne le sont pas et il faudrait, dans la mesure du possible, s'en passer.
1 - Les commentaires conditionnels
Les commentaires conditionnels sont une façon propre d'isoler une règle à Internet Explorer (depuis sa version 5).
Leur usage consiste à dire "Si le navigateur du client est IE6, alors inclure cette feuille de style complémentaire". C'est une technique que j'utilise très souvent, car malheureusement, vous vous en êtes probablement rendu compte, il est ardu, voire impossible de coder une CSS valide qui s'adaptera sans soucis à Internet Explorer.
La syntaxe des commentaires conditionnels est la suivante:
<!--[if IE]> <link rel="stylesheet" type="text/css" media="screen" href="only_ie.css"> <![endif]-->
Vous pouvez également spécifier la version (exemple, uniquement la version 6)
<!--[if IE 6]> <link rel="stylesheet" type="text/css" media="screen" href="only_ie6.css"> <![endif]-->
Ou encore, une version et les version inférieures...
<!--[if lte IE6]> <link rel="stylesheet" type="text/css" media="screen" href="only_ie.css"> <![endif]-->
...Ou supérieures
<!--[if IE gte 6]> <link rel="stylesheet" type="text/css" media="screen" href="only_ie.css"> <![endif]-->
Les commentaires conditionnels ne peuvent être inclus directement dans la feuille de style. Mettez les dans la partie head de votre document (x)html.
2 - Cacher des règles à IE
Internet Explorer ne comprends pas la règle !important.
En CSS, si un id ou classe est répétée plusieurs fois, c'est la dernière déclaration qui sera appliquée au document. la règle !important fera appliquer cette déclaration, même si elle est répétée avec des propriétés différentes.
#header{
width: 200 px !important;
width: 300px;
}
Dans cet exemple, #header aura une longueur de 200px sous Firefox (qui comprends !important et donc ne tiens pas compte de la seconde déclaration) tandis qu'IE affectera 300px de longueur à #header car il ne comprends pas la règle !important.
3 - Une règle spécifique à IE
Si une propriété est préfixée par un underscore, IE sera le seul à la comprendre.
#header{
width: 200 px;
_width: 300px;
}
Sur l'exemple ci-dessus, seul IE comprendra _width, et par conséquent, cette déclaration remplacera la précédente. Il affectera donc 300px à #header contrairement aux autres navigateurs qui, ne connaissant pas cette règle, l'ignoreront.
A noter, les déclarations préfixées d'un underscore sont marquées comme erreur dans la console d'erreur de Firefox. A utiliser uniquement en dernier recours...
4 - Transparence des images PNG
Le gros avantage des images PNG est qu'elle peuvent être transparentes, avec une qualité hautement supérieure à celle proposée par le format GIF. Malheureusement, les versions d'Internet Explorer (encore lui!) inférieures à 7 ne gèrent pas sa transparence.
Pour cela, vous avez deux options:
-Utiliser un commentaire conditionnel et spécifier qu'IE < 6 doit afficher des images GIF
au lieu des images PNG.
-Utiliser le script JavaScript suivant:
/*Correctly handle PNG transparency in Win IE 5.5 & 6.http://homepage.ntlworld.com/bobosola. Updated 18-Jan-2006.
Use in <HEAD> with DEFER keyword wrapped in conditional comments:
<!--[if lt IE 7]>
<script defer type="text/javascript" src="pngfix.js"></script>
<![endif]-->
*/
var arVersion = navigator.appVersion.split("MSIE")
var version = parseFloat(arVersion[1])
if ((version >= 5.5) && (document.body.filters))
{
for(var i=0; i<document.images.length; i++)
{
var img = document.images[i]
var imgName = img.src.toUpperCase()
if (imgName.substring(imgName.length-3, imgName.length) == "PNG")
{
var imgID = (img.id) ? "id='" + img.id + "' " : ""
var imgClass = (img.className) ? "class='" + img.className + "' " : ""
var imgTitle = (img.title) ? "title='" + img.title + "' " : "title='" + img.alt + "' "
var imgStyle = "display:inline-block;" + img.style.cssText
if (img.align == "left") imgStyle = "float:left;" + imgStyle
if (img.align == "right") imgStyle = "float:right;" + imgStyle
if (img.parentElement.href) imgStyle = "cursor:hand;" + imgStyle
var strNewHTML = "
+ " style="" + "width:" + img.width + "px; height:" + img.height + "px;" + imgStyle + ";"
+ "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader"
+ "(src=\'" + img.src + "\', sizingMethod='scale');">"
img.outerHTML = strNewHTML
i = i-1
}
}
}
Ce script permettra que votre image PNG s'affiche de manière transparente, comme c'est le cas sur Firefox ou Opera. Esthétiquement parlant, le résultat est à la hauteur, mais n'oublions pas qu'un peu moins de 10% des gens n'ont pas JavaScript activé sur leur machine.
5 - Min-Height
La propriété min-height est intéressante: Elle permet de donner une hauteur minimale à une bloc, qui pourra par la suite s'étendre verticalement si son contenu l'y oblige. Particulièrement pratique si vous avez une page avec très peu de contenu et que vous ne souhaitez pas que votre footer soit placé au beau milieu de la page...
Mais une fois de plus, l'ami IE6 rechigne à prendre cette propriété en compte. Sur ce navigateur, la propriété height à quand à elle un comportement plus ou moins semblable à min-height.
Voici le hack proposé par Dustin Diaz:
.selector {
min-height:500px;
height:auto !important;
height:500px;
}
Cette technique, respectueuse des standards est un must: Personnellement je ne peux plus m'en passer.
6 - Min-Width, Max-Width...
Encore des propriétés non implémentées par IE6 et inférieurs. Ce hack permet de contourner le problème, mais bien entendu cette syntaxe n'est absolument pas valide W3C.
Elle n'est prise en compte que par Internet Explorer, n'oubliez donc pas de spécifier normalement la propriété pour les autres browsers.
Le hack suivant simulera la propriété min-width avec une longueur minimum de 170px:
width:expression(document.body.clientWidth > 170? "170px": "auto" );
7 - Les hacks, ça craint?
Le site Stylegala à expliqué pourquoi l'usage de hacks css était déconseillé.
Leur technique de contournement est très simple mais ô combien intéressante:
Utiliser une fonction PHP pour détecter le navigateur puis générer la feuille de style avec des propriétés adaptées au navigateur utilisé par le client.
Puisque nous utilisons PHP dans cet exemple, j'en profiterais pour présenter une technique d'optimisation des CSS en PHP, présentée il y a peu par Paul Stamatiou sur son blog. Celle-ci permet de réduire une feuille de style de 35kb à environ 22Kb.
Pour mettre en pratique la solution de Stylegala, créez un fichier portant l'extension .php.
Au début du fichier, incluez ce code:
header("Content-type: text/css");
$d = detect();
$b = $d['browser'];
$v = $d['version'];
$o = $d['os'];
function detect()
{
$browser = array ("IE","OPERA","MOZILLA","NETSCAPE","FIREFOX","SAFARI");
$os = array ("WIN","MAC");
$info['browser'] = "OTHER";
$info['os'] = "OTHER";
foreach ($browser as $parent)
{
$s = strpos(strtoupper($_SERVER['HTTP_USER_AGENT']), $parent);
$f = $s + strlen($parent);
$version = substr($_SERVER['HTTP_USER_AGENT'], $f, 5);
$version = preg_replace('/[^0-9,.]/','',$version);
if ($s)
{
$info['browser'] = $parent;
$info['version'] = $version;
}
}
foreach ($os as $val)
{
if (eregi($val,strtoupper($_SERVER['HTTP_USER_AGENT']))) $info['os'] = $val;
}
return $info;
}
Le principe est simple: la fonction detect() renvoie un tableau contenant l'os, le navigateur et la version du navigateur utilisée par le client. Avec ces informations, une simple instruction conditionnelle permettra d'afficher la propriété et la valeur adéquate pour le browser que le visiteur utilise.
Exemple:
.content {
padding: 0 100px;
width: <?php
if ($o == "WIN" && $b == "IE" && $v < 6) echo "700px;"
else echo "500px;";
?>
}
Si l'OS du client est Windows, son navigateur est IE et la version du navigateur est inférieure à 6, .content aura une longueur de 700px. Dans tous les autres cas, ce sera 500px.
Et maintenant, l'optimisation de Paul Stamatiou:
A placer au tout début de votre fichier style.php:
if(extension_loaded('zlib'))
{
ob_start('ob_gzhandler');
}
header("Content-type: text/css");
A placer à la dernière ligne du fichier:
if(extension_loaded('zlib'))
{
ob_end_flush();
}
Vous pourrez en apprendre plus sur cette technique en lisant le post original.
En guise de conclusion...
Vous l'aurez remarqué, IE6 cause bien des soucis à quiconque souhaite utiliser des styles CSS proprement. Rare sont les développeurs ou intégrateurs web qui n'ont jamais été confrontés à ce problème. Heureusement, IE7 corrige certains des problèmes que j'ai exposé ici, mais il va falloir attendre encore longtemps avant qu'IE6 ai disparu du web au point ou il sera possible de ne plus le prendre en compte.
Selon moi, un des meilleurs "hacks" consiste à faire connaitre et utiliser FireFox. Malheureusement, énormément de clients et utilisateurs ne jurent encore que par le E bleu...Propagande Micro$oft quand tu nous tiens...
Autres articles dans la catégorie (x)HTML/CSS
- Les nouveautés les plus utiles de CSS3
- Tester le rendu sur différents navigateurs
- Comment détecter le navigateur
- HTML, CSS et les problèmes de navigateurs
- Un menu entièrement HTML et CSS, 2e partie
- Un menu entièrement HTML et CSS, 1e partie
- CSS: 5 possibilités haut de gamme
- XRAY, un nouvel outil efficace pour le développement web
- Appliquer une propriété uniquement à Internet Explorer 7
- Sublimez vos titres et entêtes avec CSS








Merci!
Génial comme ruse,
moi j’ai une autre solution : ignorer IE !
oui c’est du racisme anti Microsoft mais si tous les développeurs ignorer IE alors nous parlerions de ces problèmes au passé.
mais bon je vais tous de même tester tous ca…
De plus en plus de développeurs ignorent IE. malheureusement, au travail, c’est no-way…On m’a assez souvent demander d’ »optimiser » pour IE…
Perso, j’essaie de faire le maximum mais ma priorité est le respect des standarts, ce n’est pas de la faute des développeurs si IE n’est pas standart-compliant…
Je viens de trouver ce lien pour les développeurs souhaitant inviter fortement leurs visiteurs à migrer sur Firefox. ça vaut le détour
Comme je le disais dans mon post sur les PC Ubuntu de Dell, je pense que les choses sont en train de changer et Micro$oft sera bientot obligé de prendre en compte les standarts et les logiciels libres, du moins en partie.
[...] continuer à naviguer avec IE6. Par conséquent, j’ai décidé de ne pas mettre en place le script pour faire gérer la transparence PNG à IE6 sur le blog, du moins pas [...]
Bonjour,
J’ai effectuer les différentes étapes, mis le code javascript dans le fichier header.php. Malheureusement, le sous menu n’apparait pas sous IE, il est présent uniquement sous Firefox et Safari.
Quelqu’un aurait t-il une solution pour m’aider ?
D’avance merci.
Super! Très pratique ce mémo. Je le garde sous le coude
Pour ce qui est des PNG sous IE je conseil vivement ce script :
http://www.dillerdesign.com/experiment/DD_belatedPNG/
Un autre truc! Pour ceux qui veulent jouer avec la propriétée Opactity : opacity: 0.5; (par exemple) Pour IE il faut faire ceci :
-ms-filter: »progid:DXImageTransform.Microsoft.Alpha(Opacity=50) »;
filter: alpha(opacity=50);