Le langage CSS/Les sélecteurs

Un livre de Wikilivres.
Aller à : navigation, rechercher

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[modifier | modifier le wikicode]

Sélecteur universel[modifier | modifier le wikicode]

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 :

*.nom_classe {
  font-family: serif;
}

est en effet équivalent à :

.nom_classe {
  font-family: serif;
}

Sélecteur de type[modifier | modifier le wikicode]

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%;
}

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[modifier | modifier le wikicode]

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[modifier | modifier le wikicode]

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) :

<p class="nom_de_classe">...</p>

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.

Sélecteur d'identifiant[modifier | modifier le wikicode]

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 :

#nom_id {
     /* déclarations */
}

ou :

élément#nom_id {
     /* déclarations */
}

Théoriquement seule cette dernière syntaxe devrait être utilisée puisqu'un seul élément peut être affublé de l'identifiant nom_id dans la page. Il est toutefois courant de voir uniquement la première syntaxe utilisée pour des raisons de concision 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 :

<div id="nom_id">...</div>

Sélecteur d'attribut[modifier | modifier le wikicode]

À compléter...

Les autres attributs sont référençables en ajoutant [nom_attribut] à un sélecteur de type.
Exemple avec une balise input avec attribut "name" : <input name="saisie">
... La règle CSS peut s'écrire: input[name]{border:1px solid silver}.
La syntaxe complète des sélecteurs d'attributs

Les sélecteurs hiérarchiques[modifier | modifier le wikicode]

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 possible par la notion de hiérarchie des éléments du document web, conformément à l'imbrication des balises constatée dans le code de la page.

Le document HTML peut en effet être vu comme un arbre dont le tronc est l'élément html, les deux principales branches les éléments head et body, 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 html — et un ou plusieurs élément(s) enfant(s) — sauf les éléments terminant une ramification. Cela 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[modifier | modifier le wikicode]

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 :

#wikipedia h1 {... }

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 descendant mais au minimum petit-enfant 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 * comme un sélecteur descendant particulier :

#wikipedia * h1 {... }

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 #wikipedia > #contenu > .introduction > h1). 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[modifier | modifier le wikicode]

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 > puis vient l'élément enfant. Exemple :

#wikipedia > h1 {...}

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, 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 :

h1 + h2 {...}

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.

Attention : ces sélecteurs sont supportés par les principaux navigateurs modernes (y compris IE5/Mac) sauf Internet Explorer 5.0 à 6.0 pour Windows. Ceci limite beaucoup malheureusement l'intérêt de ces sélecteurs qu'on utilisera donc avec parcimonie.

Les pseudo-classes et les pseudo-éléments[modifier | modifier le wikicode]

Les sélecteurs présentés précédemment suffisent pour mettre en œuvre une page web un tant soit peu complexe. Mais d'autres sélecteurs plus précis 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.

Malheureusement leur support par les Internet Explorer 5.0, 5.5 et 6.0 de Microsoft est extrêmement réduit, ce qui limite beaucoup la portée de ces sélecteurs étant donné que la part de marché des Internet Explorer début 2007 environne les 80%. Il n'y a cependant aucune contre-indication à réserver certaines règles aux (nombreux) autres navigateurs qui les supportent, dans un souci de perfectionnisme. Il faut simplement que les pages du site ne reposent pas sur ces utilisations avancées des normes.

Ressources :

Pseudo-classes des liens[modifier | modifier le wikicode]

Les pseudo-classes :link et :visited s'adressent uniquement à des liens, donc des balises HTML <a href="…">…</a>. 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 :

a:link {color: blue;}
a:visited {color: gray;}

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 :

a:link {text-decoration: none;}
a:visited {text-decoration: line-through;}

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[modifier | modifier le wikicode]

Les pseudo-classes :hover, :active et :focus permettent de sélectionner des éléments suivant l'interaction qu'ils ont avec l'utilisateur. Les définitions du W3C sont les suivantes :

  • La pseudo-classe :hover est effective pendant que l'utilisateur désigne un élément (avec un outil quelconque), mais ne l'active pas. Par exemple, un navigateur pourra appliquer cette pseudo-classe quand le curseur (de la souris) passe au-dessus de la boîte délimitant l'élément.
  • La pseudo-class :active est effective lorsqu'un élément est activé par l'utilisateur. Par exemple pendant la durée entre laquelle l'utilisateur appuie sur le bouton de la souris puis le relâche.
  • La pseudo-classe :focus est effective lorsqu'un élément a le focus (ceci inclut les événements du clavier ou tout autre forme de saisie de texte).

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 :

input {color: #444; background-color: #fafafa;}
input:focus {color: #400; background-color: #fff;}

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 :

a {text-decoration: none;}
a:hover {text-decoration: underline;}

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 :

  • La pseudo-classes :hover s'applique théoriquement à n'importe quel élément de la page. Malheureusement les Internet Explorer 5.0, 5.5 et 6.0 de Microsoft ne la reconnaissent que sur les liens, donc les balises HTML A. En pratique on ne l'utilise donc quasiment que pour les liens.
  • La pseudo-classe :focus n'est pas disponible dans les Internet Explorer de Microsoft, version Windows.
  • La pseudo-classes :hover peut ne pas correspondre à une interaction possible de l'utilisateur, par exemple lorsque le périphérique de saisie est un stylo.

Autres pseudo-classes[modifier | modifier le wikicode]

La pseudo-classe :first-child 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. À nouveau l'utilisation de cette pseudo-classe est fortement réduite par le fait que les Internet Explorer 5.0, 5.5 et 6.0 de Microsoft ne la reconnaissent pas.

La pseudo-classe :lang permet de sélectionner des éléments correspondant à certaines langues. Il faut pour cela que les éléments concernés ou un de leur parent aie(nt) une langue spécifiée, ou encore que la page comporte une mention de langue dans l'entête. Cette pseudo-classe est d'une utilisation extrêmement marginale. Citons tout de même la possibilité de changer le caractère des guillemets utilisés pour les citations dans la balise HTML <q>…</q>. Nous utilisons en effet « et » en français alors que les anglo-saxons utilisent plutôt “ et ”.

Les pseudo-éléments[modifier | modifier le wikicode]

Les pseudo-éléments :first-line et :first-letter désigne respectivement la première ligne et le premier caractère d'un texte, typiquement un paragraphe. Par exemple le code CSS suivant :

div#page p:first-child:first-letter {font-size: 200%;}

affiche une première lettre plus grosse pour le premier paragraphe de la page.

Les pseudo-éléments :before et :after 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 content. 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):

a.prec:before {content: "\00AB ";}
a.suiv:after {content: " \00BB";}

Remarques :

  • Ces pseudo-éléments :before et :after ne sont eux aussi pas reconnus par les Internet Explorer de Microsoft, toute version.
  • Une utilisation plus poussée de :before permet de numéroter n'importe quel élément de la page automatiquement mais, bien sûr, pas dans les navigateurs de Microsoft.

Les bonnes recettes[modifier | modifier le wikicode]

Inutile de mettre des classes partout[modifier | modifier le wikicode]

L'erreur classique consiste à placer 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.

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 :

div#menu h1 {...}
div#menu ul {...}
div#menu li {...}
div#menu a {...}

Cette méthode à 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[modifier | modifier le wikicode]

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 :

  • couleur noir ou gris
  • taille 75 %, 82 % ou 100 %

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 :

.noir {color: black;}
.gris {color: gray;}
.t75 {font-size: 78%;}
.t82 {font-size: 82%;}
.t100 {font-size: 100%;}

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 :

.gris.t75 {font-weight: bold;}

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[modifier | modifier le wikicode]

Il est possible en HTML de spécifier à 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 */
div#tdm h1 {...}
div#tdm ol {...}
div#tdm li {...}

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.

« Structure et syntaxe
Valeurs et unités »