Envoyer un mail à l’auteur
xavier at ultra-fluide.com
Avec le recul, il devient évident que certaines astuces reviennent constamment dans le développement de sites web. Nous regroupons sur cette page quelques hacks CSS classiques, utiles pour assurer la compatibilité d'une page web vis à vis des principaux navigateurs.
Nous avions publié en 2003 un tutorial CSS pour la réalisation
d'un modèle 3 colonnes auto adaptable. Plusieurs hacks y étaient déjà
présents. Cet article est devenu aujourd'hui une curiosité historique : nous
pourrions proposer fin 2004 un code plus simple et plus propre pour le même
résultat. En effet, certaines astuces ont été découvertes depuis, et le
développement de IE7 (projet lancé début 2004) a changé la donne.
Ce tutorial serait donc à réécrire, en attendant, voici de quoi lever
quelques verrous :
Ecrire des règles CSS spécifiques à un navigateur ne se fait jamais de gaîté de coeur, pourtant c'est parfois un mal nécessaire. C'est ce que nous appelons le filtrage. Dans la pratique, les filtrages les plus utiles concernent Internet Explorer. Nous en donnons six répartis en trois catégories.
Ce hack repose sur le sélecteur :
* html une règle CSS
Logiquement * html
désigne un élément html descendant d'un
quelconque élément du document. Dans un document web normalement constitué,
l'élément html est l'élément racine, il ne peut être descendant d'un autre
élément. * html
désigne donc un ensemble vide d'élément et la
règle CSS qui suit ce sélecteur doit être ignorée. IE (MAC ou PC) a une
anomalie qui le conduit à un comportement opposé. Exemple :
.myclass {width:200px}
* html .myclass {width:250px}
myclass a une largeur de 200px sauf pour les différentes versions de IE qui voient une largeur de 250px.
IE MAC et IE PC sont issus de 2 projets indépendants. Il en résulte 2
logiciels très différents, chacun faisant apparaître ses propres bugs. Il est
donc souvent utile de "piloter" ces 2 IE de façon indépendante.
Ce hack repose sur le fait que IE MAC considère l'antislash comme un
caractère d'échappement même au sein d'un commentaire. Il existe en 2
versions complémentaires :
.myclass {width:250px}
/* IE MAC ne voit pas la fin de commentaire sur cette ligne \*/
.myclass {width:200px}
/* IE MAC voit un commentaire sur 3 lignes se terminant ici */
myclass a une largeur de 200px sauf pour IE MAC qui voit une largeur de 250px.
.myclass {width:200px}
/* IE Mac ne voit pas l'astérisque qui suit l'antislash \*//*/
.myclass {width:250px}
/**/
myclass a une largeur de 200px sauf pour IE MAC qui voit une largeur de 250px.
Dans certains cas IE MAC traite correctement la règle générale mais pas IE PC, il est donc indispensable de sélectionner IE PC. 3 Hacks pour cet objectif :
Ce hack nécessite peu de code, mais il est malheureusement épinglé par le validateur du W3C. Ceux qui ont une contrainte forte à ce sujet doivent se replier sur le second paragraphe.
L'astuce repose sur le fait que IE PC ignore l'underscore placé devant une propriété (alors que les autres navigateurs, comme le validateur, y voient une erreur de syntaxe et ignore la chose). Exemple :
.myclass {_width:250px;width:200px}
myclass a une largeur de 200px sauf pour IE PC qui voit une largeur de 250px.
Il s'agit simplement d'une combinaison de "seulement IE (MAC ou PC)" et "seulement IE MAC". Exemple :
.myclass {width:250px}
/* IE MAC ne voit pas la fin de commentaire sur cette ligne \*/>
* html .myclass {width:200px}
/* IE MAC voit un commentaire sur 3 lignes se terminant ici */
myclass a une largeur de 200px sauf pour IE PC qui voit une largeur de 250px.
Ce hack repose sur le fait que IE PC ne reconnaît pas le sélecteur > (sélecteur signifiant "fils de") :
.myclass {width:250px}
*>.myclass {width:200px}
myclass a une largeur de 200px sauf pour IE PC qui voit une largeur de 250px.
Min-height
est une propriété indispensable lorsqu'on définit
une présentation générique (taille du contenu inconnu lors du codage de la
mise en page). Malheureusement cette propriété est particulièrement
maltraitée :
height
à peu
près comme min-height
;height
conformément à la norme ;La diversité des comportements des navigateurs non conformes et des
filtres nécessaires pour s'adapter à ces navigateurs rend l'usage de
min-height
particulièrement mal aisé.
Nous avons testé différents contournements, beaucoup présentent des effets de
bord et conduisent à un code lourd. Finalement nous avons opté pour un
abandon de min-height
au profit d'une astuce qui simule
min-height
et fonctionne sur tous les navigateurs testés (Opéra,
Mozilla, IE5+, IE Mac, Safari). En fait, compte tenu de la simplicité du
mécanisme, et de sa parfaite conformité à CSS, la compatibilité doit être
bien plus large.
Le hack repose sur l'imbrication de deux div :
Un article de septembre 2004 présente dans le détail ce hack min-height en anglais. Voici une synthèse :
<style type="text/css">
#out-min-height {
padding-top:200px; /* voici le min-height (200px) */
min-height: 1px; /* pour Opéra */
}
#in-min-height {
margin-top: -200px /* pour compenser le padding-top */
}
</style>
<body>
<div id="out-min-height">
<div id="in-min-height">
Votre contenu ici, long ou court à votre guise.
</div>
</div>
</body>
Nous avons simplifié la technique présentée dans l'article anglo-saxon,
puisque IE Mac et PC acceptent parfaitement (en mode normal, comme en mode
quirk) le principe de du hack, il n'est nullement besoin de les apprivoiser
par du code spécifique comme décrit dans l'article.
Opéra en revanche ne réagit correctement que si la propriété
height
est explicitement positionnée, ce qui nécessite l'emploi
de min-height:1px
.
La norme CSS prévoit de laisser la valeur par défaut de certaines propriétés à la discrétion du navigateur. Ainsi, ne pas définir explicitement la valeur donne un résultat arbitraire (ce qui ne veut pas dire incorrect) selon les navigateurs. Cette situation peut, pour certaines de mise en page ou design, induire des complications dans le développement, notamment lorsque des éléments graphiques doivent subir un positionnement précis.
L'exemple bien connu concerne les margin
et
padding
des éléments tels que <p>
,
<ul>
, <li>
...
Lorsque le développeur est confronté au phénomène, il doit expliciter les
valeurs margin
et padding
pour de nombreux
éléments. Il s'aperçoit alors qu'une bonne partie des valeurs spécifiées le
sont à 0.
Dans ce cas nous préconisons une harmonisation globale pour mettre l'ensemble des navigateurs au même régime :
<style type="text/css">
* {margin:0;padding:0}
....
autres règles CSS spécifiques
</style>
Ainsi, les marges et les padding de l'ensemble des éléments sont à 0 pour tous des navigateurs.
IE7 est un projet conduit par Dean Edwards depuis début 2004. Dean fournit une large documentation en anglais. En synthèse IE7 est un ensemble de javascripts, codés avec élégance, visant à améliorer le comportement de IE relativement au standard CSS.
IE7 s'applique aux versions IE PC à partir de la version 5. IE7 améliore IE sur une bonne quarantaine de points parmi lesquels :
Nous préconisons un emploi modéré de IE7, c'est à dire lorsque les apports ne sont pas strictement indispensables à la consultation du site web. Il est tentant d'utiliser IE7 sur l'ensemble de son champ d'action, il nous parait cependant plus prudent de se prémunir d'une éventuelle absence de cet artifice. En effet :
Mieux vaut donc faire comme si IE7 n'existait pas pour un socle de base, puis en tirer tout le bénéfice possible pour des améliorations qui souvent restent de l'ordre de l'esthétique. La frontière n'est pas forcement nette, et dépendra du site à coder. Pour ce qui nous concerne, nous utilisons couramment :
En revanche nous mettons de coté, avec regret, le modèle de boîte standard. En espérant cependant que cela donnera envie d'y regarder de plus près, le téléchargement est de IE7 est sur sourceforge...
La règle horizontale <hr />
n'est plus très souvent
utilisée aujourd'hui pour 2 raisons :
C'est regrettable, car introduire un contenu fictif pour la présentation
engendre un code peu esthétique et incorrect sur le plan sémantique. Donc
rien de mieux pour introduire une séparation entre 2 contenus que l'emploi de
<hr />
.
Rangeons rapidement en 2 catégories les raisons qui tourmentent
l'utilisateur de <hr />
:
Concernant la première catégorie, il suffit d'expliciter les propriétés. Cela concerne principalement les caractéristiques des bordures, le problème peut se régler simplement en supprimant les bordures (qui peuvent parfois causer quelques soucis sous Opéra). Il est également nécessaire de spécifier la hauteur qui varie d'un navigateur à l'autre.
Dans la seconde catégorie, nous ne parlerons pour simplifier que de IE. Concernant la couleur, IE refuse d'exploiter la propriété background-color, il y a donc lieu d'utiliser en parallèle color et background-color.
Toujours concernant IE : pour ce navigateur <hr />
est
un élément inline d'une hauteur de 7 pixels par défaut et pourvu de padding
haut et bas figés à 7 pixels. Il suffit donc d'imposer à l'élément la
propriété block, et d'introduire des marges négatives de 7 pixels.
<style type="text/css">
hr {
display:block;
height: 1px;
margin: 0;
_margin: -7px 0;
padding: 0;
color: #F00;
background-color: #F00;
border: 0;
}
</style>
<body>
<div>Premier contenu</div>
<hr />
<div>Second contenu</div>
</body>
Ainsi les 2 contenus sont séparés d'une ligne rouge de 1 pixel d'épaisseur
ne comportant aucune marge. Il est toujours possible d'ajouter des espaces
soit sur les <div>
soit sur l'élément <hr
/>
lui-même en tenant compte des -7px pour IE.
Il vous est peut-être déjà arrivé de constater, au survol de la souris, le scintillement (voire le clignotement) d'images ou de zones d'une page web affichées dans Internet Explorer. L'effet est particulièrement désagréable visuellement, et totalement absent des autres navigateurs.
L'apparition de cet effet est cantonnée à des conditions très précises, mais dont la survenue n'est pas improbable :
:hover
pour modifier
les caractéristiques d'une propriété background faisant appel à une
image.Au survol de la souris, le navigateur doit évaluer les règles attachées à
:hover
pour modifications éventuelles de l'affichage. Le
navigateur doit se saisir des images impliquées dans ces modifications. Les
conditions données au-dessus activent un bug de IE6 : ce navigateur fait
systématiquement appel au serveur pour récupérer les images au lieu de passer
par son cache.
Cet effet de scintillement ou clignotement traduit la latence nécessaire à obtenir l'image du serveur. Il dépend donc du poids des images impliquées, de la charge du serveur et de la bande passante.
L'effet visuel est vraiment désagréable, mais pire encore, ce comportement sollicite inutilement le serveur et le réseau. Ainsi sur une visite, on pourra couramment constater des dizaines ou des centaines de requête http inutiles. Il est donc important de se prémunir contre ce bug. Le choix radical consiste à bannir les images des effets au survol de la souris. Voici une autre solution pour ceux qui souhaitent ne pas en arriver à cette extrémité.
Cette technique n'impose aucune contrainte sur le code de la page web, mais nécessite en revanche l'accès au fichier de paramétrage du serveur web (httpd.conf ou .htaccess s'il s'agit d'Apache).
L'astuce consiste à positionner explicitement les champs
Cache-Control
et Expires
de l'entête Http lors des
échanges avec le serveur web. Ces paramètres définissent le fonctionnement
des systèmes de cache. Le protocole Http (ce lien ouvre une nouvelle fenêtre) précise qu'un
système de cache doit prendre en compte en priorité les paramètres de
Cache-Control
quitte à surcharger les valeurs par défaut qui en
règlent l'algorithme localement. IE6 se conforme à la règle, et consulte
l'entête Http pour piloter la gestion de son cache.
Il suffit donc de spécifier explicitement, pour les objets qui induisent le scintillement, une durée de vie suffisante. Ainsi IE6 ne se croit plus obligé de rafraichir son cache à propos d'objets apparaissant encore valides. Nous proposons le paramétrage Http suivant :
Cache-Control : max-age=A36000
La durée de vie de l'objet transporté dans un message Http comportant cette entête sera de 36 000 secondes soit 10 heures. Le scintillement disparaît, et le navigateur n'ira plus chercher l'objet sur le serveur pendant 10 heures. On peut bien entendu allonger ce délai de manière à ce que des visites successives étalées sur quelques jours ne nécessitent pas le rapatriement des images.
Nous donnons ci-dessous le paramétrage Apache qui convient pour obtenir l'entête Http que nous avons proposé :
ExpiresActive On
ExpiresByType image/gif A36000
ExpiresByType image/jpeg A36000
ExpiresByType image/png A36000
ExpiresByType application/x-javascript A36000
ExpiresByType text/css A36000
Voici les conditions à remplir pour le fonctionnement de ce paramètrage :
A noter qu'il est possible de forcer la mise en cache pour toute nature d'objet, et notamment c'est bien utile, pour les scripts et les feuilles de style.
Agence de communication Ultra-Fluide : 01 47 70 23 32 - contact at ultra-fluide.com - 44 rue Richer 75009 Paris.