Envoyer un mail à l’auteur
xavier at ultra-fluide.com

Ressources

Quelques hacks CSS.

Sommaire

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 :

Filtrage du navigateur

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.

Seulement IE (MAC ou PC)

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.

Seulement IE MAC

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 :

1/ Tous sauf IE MAC

     .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.

2/ Rien que IE MAC

     .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.

Seulement IE PC

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 :

1/ légèreté sur le plan syntaxique

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.

2/ valide mais lourd

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.

3/ Tous sauf IE PC

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

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 :

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.

Margin et padding

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

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...

<hr /> horizontal rule, autrement dit règle horizontale

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.

Scintillement des images sous 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.

Conditions

L'apparition de cet effet est cantonnée à des conditions très précises, mais dont la survenue n'est pas improbable :

Que se passe-t-il donc ?

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é.

Paramétrage du serveur web

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.