Prenons l'exemple de ce bout de code HTML :

<div id="exemple">
  <h1>Titre</h1>
  <ul>
    <li><a href="section1.html">Section 1</a></li>
    <li>
      <a href="section2.html">Section 2</a>
      <ul>
        <li><a href="section2-1.html">Section 2.1</a></li>
        <li>
          <a href="section2-2.html">Section 2.2</a>
          <ul>
            <li><a href="section2-2-1.html">Section 2.2.1</a></li>
            <li><a href="section2-2-2.html">Section 2.2.2</a></li>
          </ul>
        </li>
        <li><a href="section2-3.html">Section 2.3</a></li>
      </ul>
    </li>
    <li><a href="section3.html">Section 3</a></li>
    <li><a href="section4.html">Section 4</a></li>
    <li><a href="section5.html">Section 5</a></li>
  </ul>
</div>

Nous voulons que chaque élément de liste ait une bordure en haut, sauf le premier de chaque liste, et que les listes imbriquées aient une couleur d'arrière-plan différente de celle de la liste qui la contient. Pour corser les choses, le deuxième élément de chaque liste doit avoir son texte en gras.

Il est possible de réaliser cette volonté sans qu'on touche au code HTML, en codant, par exemple, le code CSS suivant :

/* Texte en gras pour le deuxième élément li de chaque liste */
#exemple li:first-child + li {
  font-weight: bold;
}
/* Si ce deuxième élément contient une liste,
   seul le deuxième élément de cette dernière est en gras
   (le reste est en graisse normale) */
#exemple li > ul {
  font-weight: normal;
}
/* Bordure */
#exemple li {
  border-top: 1px solid black;
}
/* Pas de bordure pour chaque premier élément li */
#exemple li:first-child {
  border-top: none;
}
/* Couleurs d'arrière-plan différentes pour les listes selon leur niveau */
#exemple > ul {
  background-color: yellow;
}
#exemple > ul > li > ul {
  background-color: orange;
}
#exemple > ul > li > ul > li > ul {
  background-color: red;
}

Pour résumer, nous recourons aux sélecteurs d'élément enfant (>) et adjacent (+), ainsi qu'à une pseudo-classe (:first-child), pour traiter les différents niveaux de liste. Et ça marche sous Firefox 2, Opera 9 et Safari 3, ainsi que sous Internet Explorer 7.

Ça ne marche pas sous IE 6, me direz-vous. C'est un fait, certes ; mais, cela ne doit pas être une excuse pour mépriser les sélecteurs évoqués ci-dessus, sous prétexte que cela compliquerait la maintenance pour les intégrateurs ou que tout ce qui en CSS n'est pas compris par IE 6 est à ignorer parce que les utilisateurs d'IE 6 sont la cible principale.

Pour ma part, j'estime que la maintenance est plus compliquée lorsqu'on doit ajouter des attributs class (ou quelques id lorsque le contexte du code HTML le permet), au risque de friser la classite aiguë (comme dirait Raphaël Goetter), alors qu'en utilisant toute la puissance des CSS, notamment grâce à ses sélecteurs, on garde la faculté d'alléger le code HTML (et donc de réaliser des économies de bande passante, même s'il ne s'agit que de quelques kilo-octets ;) ).

Cela ne veut pas dire, pour autant, qu'il faille interdire l'utilisation des classes en CSS. Si l'on souhaite ou doit tenir compte d'IE 6, on peut s'en servir dans notre exemple (pour distinguer les éléments li devant être mis en gras). Mais, la classe ajoutée ne servira qu'au correctif pour IE 6 si l'on veut y reproduire le style recherché. Auquel cas il faudra créer une feuille de style à part, qui ne servira que pour IE 6 (et les versions antérieures à la 6, si l'on veut) et qu'on appellera par un commentaire conditionnel. C'est une méthode à la fois plus pérenne et plus propre, en ce sens qu'une fois qu'IE 6 aura disparu du marché des navigateurs (et plus vite il disparaîtra, mieux ce sera :-| ), on pourra non seulement ôter les classes du code HTML, mais surtout supprimer la feuille de style pour IE 6, sans qu'on ait besoin de maintenir la feuille de style principale, contrairement à la méthode des hacks CSS (ou de l'utilisation d'une seule feuille de style, qui mélange règles CSS standards et corrections pour IE), qui pollue une feuille de style qui, après tout, ne doit contenir que des règles CSS conçues pour être appliquées sans broncher par les navigateurs, à commencer par ceux qui respectent les standards.

On peut en dire tout autant concernant les images en PNG contenant une couche de transparence. Sous prétexte qu'IE 6 ne gère pas nativement la transparence du format PNG, beaucoup en viennent à brider la créativité en matière de design Web, en se contentant du format GIF pour utiliser de la transparence, mais sans pouvoir utiliser de couche Alpha ni aller au-delà de 256 couleurs (ce qui condamne l'utilisation de dégradés de couleurs). Si l'on souhaite ou doit tenir compte d'IE 6, même motif, même punition que pour les CSS : un commentaire conditionnel, où l'on remplacera le PNG qui ne passe pas par un GIF ou, mieux, par un JPEG équivalent, l'idéal étant que l'image en question soit une image générée en CSS (même si l'on peut utiliser les commentaires conditionnels pour afficher ou masquer un contenu HTML à Internet Explorer).

Et je ne vais pas me hasarder à parler du DOM et de la manière standard de parcourir l'arborescence d'un document HTML, où l'on peut jongler à merveille entre les liens de parenté qu'entretiennent les élements entre eux, voire boucler entre éléments frères. ;)

Bref, tout cela pour dire que, malheureusement, même dans le milieu des agences Web, on continue encore à coder « à la cochonne », en n'osant pas exploiter à fond toutes les possibilités des CSS parce qu'on reste prisonnier d'un navigateur et d'une version qui ne respectent pas les standards du Web : on crée des classes pour sélectionner le premier élément enfant, on pollue la feuille de style principale de hacks et de propriétés CSS propriétaires (comme filter ou zoom) qui l'invalident dès qu'elle passe au validateur CSS du W3C… Même s'il faut tenir compte des problèmes de compatibilité entre les navigateurs et entre les versions d'un même navigateur, il ne faut pas rester prisonnier de ce cancre qu'est Internet Explorer 6, d'autant moins que la version 7 fait son bonhomme de chemin, que la version 8 pointe déjà son nez et qu'un code pérenne doit se tourner vers cet avenir, de plus en plus présent, qu'est la généralisation des standards du Web.

Il est important d'avancer en CSS ; sinon, nous en serions à coder en mode Quirks, ce qui n'arrangerait pas du tout le W3C, dont le travail essentiel est de faire en sorte que, sur le Web, tout le monde parle les mêmes langages côté client, afin de faciliter la tâche des concepteurs de sites.