Sélecteurs, identifiants et classes

Il existe plusieurs manières d'appliquer des styles aux éléments d'un document web à travers la notion de « sélecteurs ». On use (et abuse) souvent de deux d'entre eux, les sélecteurs de classes et les sélecteurs d'ID, mais pourrions-nous nous en passer ?

Prenons le code d'une page qui pourrait se présenter comme suit :

<body>
    <nav id="access"></nav>
    <header id="header"></header>
    <article id="main"></article>
    <footer id="footer"></footer>
    <nav id="up"></nav>
</body>
Code HTML que l'on souhaite styliser.

Pour appliquer des styles à ces différents éléments, on peut soit passer par leur identifiant, soit utiliser d'autres sélecteurs, plus générique :

#access { }                 /* styles pour #access */
#header { }                 /* styles pour #header */
#main { }                   /* styles pour #main */
#footer { }                 /* styles pour #footer */
#up { }                     /* styles pour #up */
Application de styles par les identifiants.
body > nav:first-child { }  /* styles pour #access */
body > header { }           /* styles pour #header */
body > article { }          /* styles pour #main */
body > footer { }           /* styles pour #footer */
body > nav:last-child { }   /* styles pour #up */
Application de styles par d'autres sélecteurs.

La différence entre les deux techniques ? Dans le dernier cas, nous n'avons pas besoin d'identifier les éléments et le code HTML aurait tout aussi bien pu s'écrire comme suit :

<body>
    <nav></nav>
    <header></header>
    <article></article>
    <footer></footer>
    <nav></nav>
</body>
Code HTML simplifié et toujours stylisable.

Nous remarquons cependant qu'à l'écriture, la méthode évitant les identifiants nécessite des sélecteurs plus complexes. Pourrions-nous considérer alors que la stylisation par identifiant est plus « facile » à interpréter pour le navigateur web ? Qu'il aurait moins de calculs à effectuer pour retrouver la cible des règles ?

A titre de comparaison, voyons comment nous devrions cibler les mêmes éléments en javascript - nav#access par exemple - à travers l'API DOM. Avec l'identifiant, rien de plus simple :

var access = document.getElementById('access');
Référence à l'élément nav#access grâce à son identifiant.

Sans identifiant, le code serait un plus long. Si on suppose que l'API DOM 3 est disponible :

var el, access, i, n = document.body.children.length;
for (i = 0; i < n; i++) {
    el = document.body.children[i];
    if (el.nodeName === 'nav') {
        access = el;
        break;
    }
}
Tentative de récupérer l'élément nav#access sans utiliser son identifiant.

Cette dernière technique est évidemment absurde à partir du moment où l'on a un identifiant à disposition mais la question demeure : avec l'avènement des spécifications CSS 3, il devient possible de cibler de plus en plus finement les différents éléments d'un document web. Si bien que certains en viennent à penser qu'identifiants et classes sont devenus inutiles, et s'amusent donc à coder sans utiliser le moindre attribut...

Déclarer des identifiants et des classes peut évidemment alourdir le code HTML (et son écriture) mais il serait erroné de croire que leur utilisation n'a pour seul but que l'application de styles ou la correction des lacunes de IE(1). Les identifiants sont des ancres au sein d'un document auxquelles on peut se référer à la fois en HTML et en javascript. Les classes définissent des ensembles logiques qui peuvent eux aussi servir à tout autre chose que l'application de règles css.

De plus, leur usage purement « visuel » n'est pas entièrement obsolète car il est parfois difficile de cibler des éléments lorsqu'ils se trouvent un peu n'importe où dans le document. Le « no ids, no classes » est un bel exercice de style mais il montre vite ses limites.

Néanmoins, avec la disparition programmée de IE 6 et 7, les évolutions CSS3 (sélecteurs plus riches) et HTML 5 (plus d'élements), il sera de plus en plus facile de limiter l'usage des identifiants et des classes au strict nécessaire, l'identification d'un élément ou la définition d'ensembles qui font sens pour le document.

Pour aller plus loin :

RAGGETT, Dave ; LE, Hors ; JACOBS, Ian. Spécification HTML 4.01. W3C, . 7.5.2. Les identifiants des éléments : les attributs id et class

BOS, Bert ; ÇELIK, Tantek ; HICKSON, Ian, et al.. CSS 2.1 Specification. W3C, . 5. Selectors

ÇELIK, Tantek ; ETEMAD, Elika ; GLAZMAN, Daniel, et al.. Selectors Level 3. W3C,

HYATT, David. Writing Efficient CSS for use in the Mozilla UI. Mozilla Developper Center, . Un article plutôt ancien (les navigateurs ont fait des progrès depuis) mais qui reste intéressant.

INMAN, Shaun. CSS qualified selectors. shauninman.com, . Sur une fonctionnalité qui manque encore aux sélecteurs : un sélecteur « ascendant ».

SOUDERS, Steve. Performance Impact of CSS Selectors. High Performance Web Sites blog,

KAMEN, Croc. Hello. camendesign.com, . Un exemple réussi de la stratégie « no ids, no classes ».