Le langage CSS/Les sélecteurs
Introduction.
Si vous êtes pressé consultez en priorité :
Nous avons vu qu'il est facile avec les CSS de changer le style de tous les éléments d'une page web, par exemple mettre en gras tous les titres de niveau 2. Néanmoins, il arrive souvent que le style d'un élément dépende de son contexte. Par exemple un titre de niveau 2 dans le texte de la page ne sera certainement pas mis en forme de la même manière qu'un titre de même niveau dans une section de menu latéral (comme le menu sur la gauche de cette page). Il faut donc un outil pour restreindre le champ d'application d'une règle CSS à une catégorie particulière d'un ou plusieurs élément(s) donné(s) : ce sont les "sélecteurs CSS".
Un sélecteur CSS est un mot-clef qui permet de désigner une catégorie d'éléments de la page éventuellement de nature différente ou une relation entre deux éléments. On pourra par exemple sélectionner tous les titres de niveau 2 dans le menu, ou encore tous les éléments que l'on a marqués comme étant en rouge. Pour ce faire, les sélecteurs CSS trient les éléments de la page selon leur type, certains de leurs attributs, selon leur imbrication dans le code de la page ou encore selon l'interaction avec l'utilisateur pour les liens par exemple (liste non exhaustive).
Il est possible d'utiliser autant de sélecteurs que nécessaire pour spécifier l'élément dont on veut changer le style. On peut donc combiner comme on veut les différents types de sélecteurs qui sont décrits ci-après. Cette caractéristique confère une grande polyvalence aux règles CSS.
Sélecteurs généraux.
Sélecteur universel.
Le sélecteur étoile (*) sélectionne toutes les balises du document web.
Si on souhaite modifier la police de tout le document, on pourra donc employer :
 font-family: serif;
Le sélecteur universel peut trouver d'autres applications dans l'imbrication d'éléments (voir Le sélecteur de descendant plus loin).
Il est en effet optionnel lorsqu'il est accolé à un autre sélecteur, ce qui le rend généralement peu utile :
 font-family: serif;
est en effet équivalent à :
.nom_classe
 font-family: serif;
Sélecteur de type.
D'un point de vue de la sémantique employée par le W3C, lorsqu'on utilise "h2" pour changer le style de tous les titres de niveau 2, on utilise un sélecteur de type.
Un sélecteur de type est donc le nom d'une balise dans la page web.
Exemple :
h2
 font-size: 150%;
Cet exemple fixe la taille de la police pour les titres de niveau 2 à 150 % de la police normale.
Il s'agit bien évidemment d'un sélecteur extrêmement courant d'utilisation.
Sélecteurs d'attributs.
Un sélecteur CSS peut faire référence à un attribut d'un élément HTML. Les deux attributs les plus couramment utilisés sont class et id mais il est possible de se référer à n'importe quel attribut. La classe "class" permet d'attribuer des styles génériques (par exemple une classe "petit" pour mettre du texte plus petit) alors que l'identifiant "id" sert à repérer un élément différent des autres dans la page (par exemple la zone de menu).
Sélecteur de classe.
Le sélecteur de classe s'applique typiquement à des éléments redondants dans la page. Il est spécifié en CSS par un point ( . ) et peut concerner tous les éléments HTML utilisant cette classe ou seulement l'un d'entre eux. La syntaxe CSS est la suivante :
 ."nom_de_classe" {
 /* déclaration(s) */
 "élément"."nom_de_classe" {
 /* déclaration(s) */
Dans le document HTML, on se réfère à cette classe de la sorte (exemple pour l'élément P) :
 "nom_de_classe"">...
N'importe quel élément HTML de la page peut utiliser cette classe :
<p class="nom_de_classe">...</p>
<ul class="nom_de_classe">
 <li>...</li>
 <li>...</li>
</ul>
Ce qui n'empêche pas par la suite de définir des règles communes à tous ces éléments et d'autres spécifiques à certains d'entre eux :
 ."nom_de_classe" {
 color: gray;
 p."nom_de_classe" {
 font-style: italic;
Ici les éléments de classe "nom_de_classe" sont affichés en gris et les paragraphes de cette classe ont en plus leur texte en italique.
Il est possible de sélectionner les éléments ayant plusieurs classes en accolant les sélecteurs :
.menu.sombre {
 /* Style pour les éléments ayant à la fois la classe "menu" et "sombre", quel que soit l'ordre. */
Sélecteur d'identifiant.
Le sélecteur d'identifiant (ID) ne peut être appliqué qu'à un seul élément dans le code HTML, par exemple un seul paragraphe. Il concerne donc les éléments uniques de structuration du document, comme les blocs principaux (logo, en-tête, colonne(s), pied de page...). 
Le sélecteur d'identifiant est spécifié en CSS par un dièse ( # ), la syntaxe est la suivante :
 élément#nom_id {
 /* déclarations */
ou :
 #nom_id {
 /* déclarations */
Théoriquement seule cette dernière syntaxe devrait être utilisée puisqu'un seul élément peut se voir attribué l'identifiant "nom_id" dans la page. Il est toutefois courant de voir la première syntaxe utilisée pour des raisons de lisibilité du code. 
Dans un document HTML, si l'identifiant "nom_id" se rapporte à un élément de type "div", on ne doit écrire qu'une seule et unique fois dans la page :
Sélecteur d'attribut.
Les autres attributs sont référençables en spécifiant le nom de l'attribut entre crochets.
 [nom_attribut]
Exemple avec une balise input avec attribut "name" :
<input name="saisie">
Un sélecteur pour les éléments input avec un attribut name s'écrit :
/* Tous les éléments input avec un attribut name */
input[name]
 border:solid 1px silver; /* ajouter une bordure argentée de 1 pixel. */
Le sélecteur peut ne pas spécifier de nom d'élément :
/* Tous les éléments avec un attribut name */
[name]
 border:solid 1px silver; /* ajouter une bordure argentée de 1 pixel. */
La syntaxe précédente ne spécifie pas quelle valeur doit avoir l'attribut.
Il suffit juste qu'il soit spécifié.
On peut cependant ajouter la valeur après un signe égal :
/* Tous les éléments avec un attribut name qui vaut "adresse" */
[name="adresse"]
 border:solid 1px silver; /* ajouter une bordure argentée de 1 pixel. */
Il y a différentes syntaxes pour sélectionner des éléments par leur attributs :
Les sélecteurs hiérarchiques.
Une caractéristique fondamentale des règles CSS est que l'on peut spécifier des règles pour les éléments contenus à l'intérieur de certains autres éléments sans ajouter de classe ni d'identifiant. Concrètement, on peut par exemple changer le style d'un lien selon qu'il est dans un paragraphe ou dans une liste. Ceci est rendu possible par la notion de hiérarchie des éléments du document web, conformément à l'imbrication des balises dans le code de la page.
Le document HTML peut en effet être vu comme un arbre dont le tronc est l'élément codice_1, les deux principales branches les éléments codice_2 et codice_3, desquelles partent en ramification toutes les autres branches. Un sélecteur suit ces ramifications, comme une branche de lierre, en partant du tronc, pour désigner une ou des branches — qui sont des éléments HTML. Ainsi, chaque élément a un élément "parent" — sauf l'élément racine codice_1 — et un ou plusieurs "élément(s) enfant(s)" — sauf les éléments terminant une ramification. Ceci définit une hiérarchie dans laquelle il faut pouvoir s'orienter facilement et précisément.
La grammaire CSS définit plusieurs types de sélecteurs pour parcourir l'arbre qu'est le document HTML.
Le sélecteur de descendant.
Le sélecteur de descendant, noté par un ou plusieurs espace(s), permet de désigner les éléments qui sont des descendants d'un autre élément (ou de plusieurs), c'est-à-dire liés les uns aux autres par une relation de parenté quelconque. Le dernier élément est inclus directement ou non dans celui qui le précède et ainsi de suite.
Exemple :
désigne tous les éléments "h1" contenus, à quelque niveau que ce soit, dans les éléments d'identifiant "wikipedia". Cet exemple illustre pourquoi ce sélecteur est d'utilisation courante : il permet de modifier le style d'éléments enfants sans avoir à les marquer d'une classe ou d'un identifiant.
On peut vouloir aussi désigner des éléments descendants mais au minimum petits-enfants dans la hiérarchie mais il peut être laborieux d'expliciter tout le ou les chemin(s) jusqu'aux éléments concernés. Il est possible d'utiliser alors codice_5 comme un sélecteur descendant particulier :
Ce sélecteur désigne tous les éléments "h1" petits-enfants d'éléments d'identifiant "wikipedia", ou situés plus loin dans la hiérarchie du document (par exemple codice_6). Ainsi dans le code HTML suivant :
<div id="wikipedia">
 <h1> Nom du site </h1>
 <div id="contenu">
 <h1> Titre 1 </h1>
 <p>Paragraphe...</p>
 <h2> Titre 1.1 </h2>
 <p>Paragraphe...</p>
 </div>
</div>
les deux titres "h1" seraient affectés par la première règle mais seul le deuxième titre de texte « Titre 1 » serait affecté par la seconde.
"Tous ces sélecteurs sont supportés par les principaux navigateurs modernes (Internet Explorer, Mozilla, Firefox, Opera...)"
Les sélecteurs d'enfant et de frère adjacent.
Le sélecteur d'enfant, noté >, permet de désigner un élément par filiation directe à un autre élément. La relation ne concerne donc que les enfants et non les petits-enfants ou plus. L'élément parent est suivi de codice_7 puis vient l'élément enfant.
Exemple :
désigne tous les éléments "h1" enfants d'éléments d'identifiant "wikipedia". Les espaces ne sont pas obligatoires bien qu'ils rendent la syntaxe plus claire.
Le sélecteur de frère adjacent 'ou sélecteur d'adjacence directe), noté +, permet de définir un style pour un élément enfant suivant immédiatement un autre élément enfant du même élément parent. La relation de filiation est donc à nouveau directe.
Exemple :
applique un style à l'élément "h2" qui suivrait immédiatement un élément "h1". Ainsi dans le code HTML suivant :
<div class="wikipedia">
 <h1> Titre 1 </h1>
 <h2> Titre 1.1 </h2>
 <p>Paragraphe...</p>
 <h2> Titre 1.2 </h2>
 <p>Paragraphe...</p>
</div>
seul le titre de texte « Titre 1.1 » serait affecté par les règles de style.
Enfin, le sélecteur d'adjacence indirecte est noté codice_8.
Les pseudo-classes et les pseudo-éléments.
Les sélecteurs présentés précédemment suffisent pour mettre en œuvre des pages web déjà complexes. Pour aller plus loin, d'autres sélecteurs permettent de modifier le style d'éléments dans un état spécifique comme les liens visités ou non, les états correspondant à l'interaction de l'utilisateur ou encore des éléments répondants à des critères particuliers.
Ressources :
Pseudo-classes des liens.
Les pseudo-classes codice_9 et codice_10 s'adressent uniquement à des liens, donc des balises HTML codice_11…codice_12. Le premier permet de sélectionner les liens qui n'ont pas encore été visités et le second ceux qui l'ont déjà été. Ainsi le code CSS suivant :
fait en sorte que les liens des pages non visitées soient bleus alors que ceux des pages visitées sont gris. On peut bien évidemment jouer sur toute autre propriété du lien. Un traitement mettant un peu d'originalité consiste à barrer les liens visités :
Cet effet n'est cependant pas toujours bien apprécié des lecteurs car les liens visités deviennent moins lisibles.
Pseudo-classes d'interaction avec l'utilisateur.
Les pseudo-classes codice_13, codice_14 et codice_15 permettent de sélectionner des éléments suivant l'interaction qu'ils ont avec l'utilisateur. Les définitions du W3C sont les suivantes :
Typiquement un champ de formulaire dans lequel le curseur clignote a le focus. On peut utiliser cet effet pour changer l'apparence d'un champ de formulaire et notifier son état d'interaction. Par exemple ce code CSS :
change l'apparence d'un champ de texte de gris foncé sur fond gris clair lorsqu'il est inactif, à marron foncé sur fond blanc lorsqu'il récupère le focus.
La pseudo-classe ":hover" offre de nombreuses possibilités qui vont du simple changement de couleur au survol de la souris au menu déroulant en pur CSS ! L'utilisation actuellement classique sur le web consiste à supprimer le soulignage par défaut des liens et de le faire apparaître uniquement au survol de la souris :
Enfin la pseudo-classe ":active" est d'une utilisation assez marginale, son effet étant extrêmement bref. On peut par exemple l'utiliser lors du clic sur un bouton dans un formulaire pour simuler l'enfoncement du bouton par un changement de couleur.
Remarques :
Ordre des éléments enfants.
La pseudo-classe codice_16 désigne le premier enfant d'un élément, c'est-à-dire le premier élément inclus dedans.
On peut l'utiliser pour modifier le premier paragraphe d'une page ou encore la première entrée d'une liste.
Exemple :
.document :first-child {
 /* Styles pour le premier élément enfant d'un autre de classe "document" */
.document p:first-child {
 Styles pour le premier élément enfant d'un autre de classe "document", s'il s'agit d'un élément p
 <div class="document">
 <span></span> <!-- Ne s'applique pas à cet élément (n'est pas un <p>) -->
 <p></p> <!-- Ne s'applique pas à cet élément (n'est pas premier) -->
La pseudo-classe codice_17 désigne le dernier enfant d'un élément.
Exemple :
table tr:last-child {
 /* Styles pour la dernière ligne d'une table : */
 border-bottom: solid 4px; /* Ligne plus épaisse. */
La pseudo-classe codice_18 désigne le premier enfant d'un élément ayant le type d'élément spécifié.
Notez la différence avec l'exemple précédent :
.document p:first-of-type {
 Styles pour le premier élément <p> enfant d'un autre de classe "document"
 <div class="document">
 <span></span>
 <p></p> <!-- S'applique à cet élément -->
Similairement, il y a les pseudo-classes codice_17 et codice_20 pour le dernier élément enfant.
La pseudo-classe codice_21 possède une expression simple en paramètre pour sélectionner les éléments dont la position correspond à l'expression, où a et b sont deux entiers et n est la lettre représentant un nombre entier.
La position 1 correspond au premier élément.
La pseudo-classe codice_22 est similaire pour la position en partant de la fin.
Exemples :
Inversion de condition.
La pseudo-classe codice_31 permet de sélectionner les éléments non sélectionnés par le sélecteur en paramètre.
Elle permet d'inverser une condition ou d'en exclure des éléments, et peut être combinée avec d'autres sélecteurs pour une sélection complexe :
.document:not(.exception) {
 Styles des éléments de classe "document" sauf ceux de classe "exception"
Les pseudo-éléments.
Les pseudo-éléments codice_41 et codice_42 désigne respectivement la première ligne et le premier caractère d'un texte, typiquement un paragraphe. Par exemple le code CSS suivant :
affiche une première lettre plus grosse pour le premier paragraphe de la page.
Les pseudo-éléments codice_43 et codice_44 se réfèrent au contenu de l'élément. Ils servent à ajouter du texte avant ou après le texte contenu dans l'élément grâce à la propriété CSS codice_45. On s'en sert par exemple pour symboliser les pages précédente et suivante à l'aide de liens (les encodages \00AB et \00BB désignant respectivement les guillemets doubles ouvrants et fermants français):
Remarques :
Les bonnes recettes.
Inutile de mettre des classes partout.
L'erreur classique consiste à attribuer des classes à tous les éléments de la page que l'on souhaite modifier.
Le sélecteur de descendant associé soit au sélecteur de classe, soit au sélecteur d'identifiant permet dans la très grande majorité des cas de s'en passer.
Cependant, il est nécessaire d'attribuer une classe à l'élément racine de chaque partie.
Autrement il devient, par exemple, difficile de distinguer un <div> de menu d'un <div> de paragraphe enfants du même élément, l'ordre pouvant changer.
Cela s'applique aussi aux systèmes wiki, où il est recommandé d'attribuer une classe à l'élément englobant (élément, table, ...) dans les modèles.
Prenons l'exemple d'un menu constitué de plusieurs listes de liens. On peut coder un tel menu en HTML de cette façon :
<!-- exemple surchargé en classes -->
<h1 class="menu"> Navigation </h1>
<ul class="menu">
 <li class="menu"> <a href="..."> Lien 1 </a> </li>
</ul>
<h1 class="menu"> Boîte à outils </h1>
<ul class="menu">
 <li class="menu"> <a href="..."> Lien A </a> </li>
</ul>
Noter qu'on aurait aussi pu utiliser un nom de classe différent par élément différent (par ex. "menu_title" pour les titres "h1"). En fait il n'est pas nécessaire d'ajouter une classe à chaque élément fonctionnel du menu (le titre, la liste, l'entrée, le lien) sous prétexte que ce sont des éléments HTML différents. Ainsi il suffit de placer le menu dans un élément parent de type "div" et d'identifiant "menu" :
<!-- solution habituellement rencontrée -->
<div id="menu">
 <h1> Navigation </h1>
 <ul>
 <li> <a href="..."> Lien 1 </a> </li>
 </ul>
 <h1> Boîte à outils </h1>
 <ul>
 <li> <a href="..."> Lien A </a> </li>
 </ul>
</div>
D'un point de vue de la structure de la page web, il est en plus tout-à-fait logique de placer le menu dans un élément conteneur pour le séparer du reste de la page. Ceci facilite son placement par la suite. On peut alors accéder à chaque élément fonctionnel en CSS de cette manière :
Cette méthode a l'avantage d'alléger le code HTML — qui en devient donc plus lisible, plus maintenable et moins consommateur de bande passante — tout en gardant un code CSS des plus clairs également.
Utiliser de multiples classes.
Une autre erreur courante consiste à multiplier des classes qui sont en fait des combinaisons de classes plus simples. Pour clarifier notre propos, supposons que l'on souhaite disposer de classes pour changer la couleur et/ou la taille du texte :
On est donc tenté d'introduire 6 classes combinaisons de ces 2 et 3 possibilités et nommées par exemple "noir_75p", "gris_75p", "noir_82p", etc. Ceci est inutile car il est possible en HTML d'utiliser plusieurs classes dans un même élément en les séparant simplement d'un espace. Si on définit en CSS les classes suivantes :
On pourra les combiner à souhait par la suite de cette manière :
<p class="noir t82">...</p>
<p class="gris t100">...</p>
Bien sûr dans cet exemple le gain est faible (5 classes au lieu de 6) mais nous vous laissons multiplier les possibilités ou les propriétés à pouvoir modifier pour en apprécier le gain. La méthode exposée a le grand avantage de modulariser les classes pour plus de souplesse.
Cependant l'objection que l'on pourrait faire serait qu'il n'est plus possible de modifier légèrement le style d'une combinaison particulière de certaines propriétés. Elle n'est en fait pas recevable car il est aussi possible en CSS de spécifier des combinaisons de classes pour un même élément, il suffit de les accoler dans le sélecteur.
Par exemple, un texte petit de couleur grise est difficile à lire et il pourrait être judicieux de l'afficher automatiquement en caractères gras. La combinaison des classes "gris" et "t75" peut alors être modifiée en ajoutant cette règle dans les styles CSS :
On peut combiner de la sorte autant de classes qu'on le souhaite.
Remarque : l'ordre des classes dans le code HTML n'a pas d'importance. De ce fait il est aussi plus difficile de faire une erreur de syntaxe sur les classes "noir cadre fond-jaune" non ordonnées que sur la classe "noir_cadre_fond-jaune".
Attention : comme indiqué sur la page Multiple classes (en anglais), Internet Explorer 6.0 de Microsoft n'interprète pas correctement les classes multiples.
Combiner classe et identifiant.
Il est possible en HTML d'attribuer à la fois un identifiant et une ou plusieurs classes à un même élément de la page. Cette technique permet de réaliser une sorte d'héritage de styles. À nouveau on peut en tirer profit pour réduire la diversité des styles et les concevoir d'une manière plus générique et donc plus facilement ré-utilisable.
Prenons comme exemple la table des matières (TDM) regroupant les titres de la page web. L'adaptation classique en HTML est la suivante :
<!-- table des matières -->
 <div id="tdm">
 <h1> Table des matières </h1>
 <ol>
 <li>
 <a href="#..."> Titre 1 </a>
 <ol>
 <li> <a href="#..."> Titre 1.1 </a> </li>
 </ol>
 </li>
 </ol>
 </div>
Ici les liens pointant vers les titres des sections sont placés dans des listes de liens imbriquées. Maintenant nous souhaiterions que cette table des matières soit placée soit dans un cadre flottant à droite ou à gauche du texte, soit à gauche en occupant toute la largeur de la page (positionnement par défaut), selon l'humeur de l'administrateur (ou un paramètre utilisateur ?). Le plus simple est d'ajouter simplement des classes "float" et "left" ou "right" à l'élément conteneur dans les deux premiers cas, par exemple :
<div id="tdm" class="float left">
</div>
On peut ensuite ajouter les règles suivantes dans les styles CSS :
/* classes génériques */
div.float
 margin: 0.5em; /* garder de la place pour le texte autour et dedans */
 padding: 0.5em 0.25em;
 border: 1px solid #44a; /* faire un encadré */
 background-color: #fafafa;
div.float.left
 float: left;
 margin-left: 0; /* se coller contre le bord gauche de la page */
div.float.right
 float: right;
 margin-right: 0; /* idem bord droit */
/* stylisation de la TDM */
Les classes génériques auront alors intérêt à être placées dans un fichier CSS séparé afin d'être facilement importées dans un autre projet web.
Imbrication.
L'imbrication n'est pas une fonctionnalité du standard CSS, mais de .
L'esperluette est l'opérateur d'imbrication ; il permet de raccourcir les sélecteurs en réutilisant le sélecteur parent.
Exemple 1.
.classe1 {
Cet exemple génère l'équivalent en CSS suivant :
Exemple 2.
.classe1 {
Équivaut à ceci (notez l'espace entre le & et .classe2) :
.classe1 {
Cet exemple génère l'équivalent en CSS suivant :
Exemple 3.
Autre exemple :
.classe1 {
Cet exemple génère l'équivalent en CSS suivant :