Les sélecteurs en CSS

Comme l’on a pu le voir dans précédent chapitre, les sélecteurs servent à sélectionner des éléments du DOM auxquels on souhaite appliquer des styles. Il existe cinq catégories de sélecteurs : universel, type, attribut, classe, id.

catégories de sélecteurs

sélecteur universel

Le sélecteur universel * sélectionne tous les éléments de la page. C’est un sélecteur quelque peu barbare, et par conséquent peu usité.

sélecteur de type

Il s’agit du sélecteur le plus simple, il sélectionne tous les éléments d’un type donné.

exemple

Le sélecteur blockquote sélectionne tous les éléments de type… blockquote.

Voir en ligne un exemple plus complet et commenté

HTML
<blockquote>Je suis une citation</blockquote>
CSS
blockquote {
  font-style: italic;
}

sélecteur d’attribut

Il est possible de sélectionner un élément selon ses attributs. On place pour cela l’identificateur de l’attribut entre crochets [ ]. Il est aussi possible, en utilisant différents opérateurs, de restreindre la sélection en précisant une attente concernant la valeur associée à l’attribut.

exemples

Voir en ligne un exemple plus complet et commenté ou cet exemple alternatif

HTML
<a href="#">Je suis un lien</a>

<a href="http://domain.tld">Je suis un lien</a>

<a href="monfichier.pdf">Je suis un lien</a>
CSS
[href] { /* tous les éléments avec l'attribut href*/ }

[href="http://domain.tld"] { /* tous les éléments avec l'attribut href associé à la valeur "http://domain.tld" */ }

[href$=".pdf"] { /* tous les éléments avec l'attribut href dont la valeur finit par */ }

Il existe d’autres possibilités qui sont présentées dans la documentation relative

sélecteur de classe

Il existe un raccourci pour sélectionner les éléments grâce à leur attribut class. Pour sélectionner les éléments appartenant à une même classe, on utilise l’identificateur correspondant à cette classe, préfixé par un point.

exemple

Le sélecteur .exemple sélectionne tous les éléments de ayant la classe exemple.

Voir en ligne un exemple plus complet et commenté

HTML
<section class="exemple">contenu</section>
CSS
.exemple {
  color: red;
}

sélecteur d’id

L’usage des sélecteurs d’id peut être considéré comme une mauvaise pratique1 en raison de leur forte spécificité. La spécificité est traitée plus loin dans ce chapitre.

exemple

Le sélecteur #exemple sélectionne l’élément ayant l’id exemple.

Voir en ligne un exemple plus complet et commenté

HTML
<section id="exemple">contenu</section>
CSS
#exemple {
  color: red;
}

qualification des sélecteurs

On peut noter qu’il est possible de qualifier un sélecteur (hormis les sélecteur de type et universel), en les précédant directement d’un sélecteur de type.

Qualifier un sélecteur en augmente la spécifité et en diminue la polyvalence. Il convient de pouvoir se justifier si l’on utilise cette fonctionnalité de CSS.2

exemples

p[data-exemple] { /* tous les paragraphes ayant l'attribut data-exemple */ }
p.exemple { /* tous les paragraphes ayant la classe exemple */ }
p#exemple { /* tous les paragraphes ayant l'id exemple */ }

pseudo-classes et pseudo-éléments

Les pseudo-classes et pseudo-éléments répondent à une problématique : que faire si je souhaite cibler dans ma structure de document un élément survolé par le curseur ? La première lettre ou la première ligne d’un bloc de texte ? Le premier ou le dernier élément d’une liste ?

pseudo-classe : sélectione d’élément sur la base d’une pseudo-caractéristique pseudo-élément sélection d’un pseudo-élément

pseudo-classes

Définition

1 : principe

Le concept de pseudo-classe a été introduit pour permettre des sélections basées sur des informations hors de l’arbre du document ou qui ne peut être exprimée en utilisant d’autres sélecteurs simples3

Les pseudo-classes traduisent donc un état (survolé, coché, visité) ou une nature (langue, premier ou dernier) particulière d’un élément qui vont permettre sa sélection.

2 : syntaxe

Une pseudo-class consiste toujours en un deux-point : suivi par le nom d’une pseudo-class et optionnellement d’une valeur entre parenthèses.4

liste des pseudo-classes

Les sélections possibles à l’aide de pseudo-classes sont :

Exemples

pseudo-elements

Définition

1 : principe

Les pseudos-éléments créent des abstractions de l’arbre du document au delà de ceux spécifiés par le langage du document. Par exemple, les langages de document n’offrent pas de mécanisme permettant d’accéder à la première lettre ou ligne du contenu d’un élément. Les pseudo-éléments permettent aux auteurs de faire référence à ces informations autrement inaccessibles. Les pseudo-éléments peuvent aussi fourni aux auteurs une manière d’accéder à du contenu qui n’existe pas dans le document source (par exemple les pseudo-éléments ::before et ::after donnent accès à du contenu généré).5

Contrairement aux pseudo-classes où l’on va cibler des éléments existants grâce à un état ou une nature particulière, on cible ici des éléments qui n’existent pas en temps que tels dans l’arbre du document.

2 : syntaxe

Un pseudo-element est constitué de deux deux-points (::) suivi par le nom du pseudo-élément.6

liste des pseudo-éléments

Les pseudo-éléments sont d’un nombre assez restreint à l’heure actuelle, et sont au nombre de quatre.

::first-letter et ::first-line

Les pseudos-éléments ::first-letter et ::first-line permettent respectivement de sélectionner la première lettre et la première ligne d’un élément.

::before et ::after

Les pseudos-éléments ::before et ::after peuvent être utilisés pour insérer du contenu généré avant ou après le contenu d’un élément.7

Les pseudo-éléments ::before et ::after permettent d’ajouter et de styler du contenu avant et après le contenu d’un élément. Cela peut par exemple servir à ajouter des signes typographiques décoratifs ou informatifs qui n’ont pas lieu de faire partie du contenu du document.

Combinateurs

Les combinateurs sont des caractères séparant deux sélecteur et exprimant une relation entre ceux-ci. Il existe quatre combinateurs : descendant, enfant, frère et frère adjacent.

Il est important de noter que les combinateurs ne sont en général pas très utilisés, car ceux-ci diminuent la réutilisabilité du sélecteur, augmente sa spécificité et portent ainsi atteinte à la maintenabilité du code.8

combinateur descendant

On utilise le combinateur descendant pour sélectionner un élément qui est un descendant d’un autre élément. On peut par exemple vouloir appliquer des styles particuliers à des liens, mais uniquement à des liens situés dans un élément navigation.

Le combinateur descendant consiste en une espace suivant le sélecteur de l’ancètre et précédant le sélecteur du descendant que l’on souhaite cibler.

.ancetre .descendant { /* on sélectionne tous les .descendant situés dans un .ancetre */ }

combinateur enfant

On utilise le combinateur enfant pour sélectionner un élément qui est l’enfant (le descendant direct) d’un autre élément.

Le combinateur descendant consiste en un caractère chevron fermant > suivant le sélecteur de l’élément parent et précédent l’enfant que l’on souhaite cibler.

.parent > .enfant { /* on sélectionne tous les .enfant descendants directs d'un .parent */ }

combinateur frère

Le combinateur frère (ou frère général en opposition au combinateur frère adjacent) permet de sélectionner un élément qui partage le même parent qu’un autre.

Le combinateur descendant consiste en un caractère tildre ~ suivant le sélecteur de l’élément frère de celui que l’on souhaite sélectionner, et précédent l’élément que l’on souhaite sélectionner.

.sibling ~ .cible { /* on sélectionne tous les .cible qui ont un élément .sibling frère */ }

combinateur frère adjacent

Le combinateur frère adjacent permet de sélectionner un élément qui partage le même parent qu’un autre et qui se situe juste après ce dernier.

Le combinateur descendant adjacent consiste en un caractère plus + suivant le sélecteur de l’élément frère adjacent de celui que l’on souhaite sélectionner, et précédent l’élément que l’on souhaite sélectionner.

.sibling + .cible { /* on sélectionne tous les .cible qui ont un élément .sibling frère adjacent */ }
<div class="parent">
  <div class="cible">non sélectionné</div>
  <div class="sibling">frère adjacent</div>
  <div class="cible">sélectionné</div>
</div>

<div class="parent">
  <div class="sibling">frère adjacent</div>
</div>
<div class="cible">non sélectionné</div>

important : traitement des combinateurs

Il fait savoir que les sélecteurs et combinateurs sont lus de droite à gauche par le navigateur.

Ce qui signifie que si vous renseignez le sélecteur .exemple *, vous ne sélectionnez pas tous les éléments de classe exemple pour ensuite sélectionner dans celle-ci tous les éléments descendants grâce au sélecteur universel.

En réalité, vous sélectionnez tous* les éléments de la page, et, pour chacun d’eux, vous regardez s’il a quelque part un ancètre de classe exemple.

spécificité

Nous avons vu dans le chapitre précédent que la cascade désigne le processus permettant de résoudre les conflits entre plusieurs feuilles de style (ou de déclaration et jeux de règles). La spécificité des sélecteurs est un des paramètres importants à prendre en compte dans ce processus.

L’idée de spécificité est simple : plus un sélecteur est spécifique (un type est moins spécifique qu’une classe qui est moins spécifique qu’un id), plus le bloc de déclaration qui lui est associé sera considéré comme prioritaire par la cascade.

calcul de la spécificité

On calcul la spécificité d’un sélecteur en additionnant la spécifité de tous les éléments qui le compose.

exemple

<ul>
  <li id="autre">item 1</li>
  <li id="exemple" class="special">item 2</li>
</ul>
/* spécificité égale à 1 */
li { color: grey; }

/* spécificité égale à 10 */
.special { color: blue; }

/* spécificité égale à 100 */
#exemple { color: red; }

Implications et bonnes pratiques

Imaginons que l’on souhaite que le sélecteur .special prenne le pas sur le sélecteur #exemple. Ce dernier a une spécificité dix fois supérieure. On pourrait créer un sélecteur #exemple.special, mais l’on ne ferait que déplacer le problème (que se passe-t-il si l’on veut encore outrepasser ce sélecteur ?), et il faudrait de plus pour chaque id pouvant empêcher le jeu de règles associé au sélecteur id de s’appliquer.

Ces problèmes font qu’il est déconseillé d’utiliser le sélecteur d’id et de lui préférer le sélecteur de classe non qualifié et sans combinateur1.

notes & références

W3C Candidate Recommendation 08 September 2009*, w3.org, 08 Sept. 2009. Web. 13 Mar. 2017.

  1. Voir, par exemple, Harry Roberts, CSS Guidelines, cssguidelin.es. Web 12 Mar. 2017. et/ou Airbnb CSS / Sass Styleguide, github.com. Web 12 Mar. 2017. 2

  2. Harry Roberts, CSS Guidelines, cssguidelin.es. Web 12 Mar. 2017. 

  3. “The pseudo-class concept is introduced to permit selection based on information that lies outside of the document tree or that cannot be expressed using the other simple selectors.” Tantek Çelik, Elika J. Etemad, Daniel Glazman, Ian Hickson, Peter Linss, John Williams, Selectors Level 3 W3C Recommendation 29 September 2011. w3.org, 29 Sept. 2011. Web. 10 Mar. 2017. 

  4. “A pseudo-class always consists of a “colon” (:) followed by the name of the pseudo-class and optionally by a value between parentheses.” Ibid. 

  5. “Pseudo-elements create abstractions about the document tree beyond those specified by the document language. For instance, document languages do not offer mechanisms to access the first letter or first line of an element’s content. Pseudo-elements allow authors to refer to this otherwise inaccessible information. Pseudo-elements may also provide authors a way to refer to content that does not exist in the source document (e.g., the ::before and ::after pseudo-elements give access to generated content).” Ibid. 

  6. “A pseudo-element is made of two colons (::) followed by the name of the pseudo-element.” Ibid. 

  7. “The ‘:before’ and ‘:after’ pseudo-elements can be used to insert generated content before or after an element’s content.” Bert Bos, Tantek Çelik, Ian Hickson, Håkon Wium Lie, *Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification 

  8. Harry Roberts, CSS Guidelines, cssguidelin.es. Web 13 Mar. 2017.