The CSS Podcast – 015 : Pseudo-classes
Imaginons que vous ayez un formulaire d'inscription par e-mail et que vous souhaitiez que le champ d'adresse e-mail soit entouré d'une bordure rouge s'il contient une adresse e-mail non valide.
Comment procéder ?
Vous pouvez utiliser une pseudo-classe CSS :invalid
, qui fait partie des nombreuses pseudo-classes fournies par le navigateur.
Une pseudo-classe vous permet d'appliquer des styles en fonction des changements d'état et des facteurs externes. Cela signifie que votre conception peut réagir aux saisies de l'utilisateur, comme une adresse e-mail non valide. Ces sélecteurs sont abordés dans le module Sélecteurs. Ce module vous les présentera plus en détail.
Contrairement aux pseudo-éléments, dont vous pouvez en savoir plus dans le module précédent, les pseudo-classes s'accrochent à des états spécifiques dans lesquels un élément peut se trouver, plutôt que de styliser généralement des parties de cet élément.
États interactifs
Les pseudo-classes suivantes s'appliquent en raison d'une interaction d'un utilisateur avec votre page.
:hover
Si un utilisateur dispose d'un dispositif de pointage tel qu'une souris ou un pavé tactile et qu'il le place sur un élément, vous pouvez vous accrocher à cet état avec :hover
pour appliquer des styles.
C'est un moyen utile de suggérer qu'un élément peut être utilisé.
:active
Cet état est déclenché lorsqu'un élément est en cours d'interaction (par exemple, un clic) avant que le clic ne soit relâché. Si un dispositif de pointage tel qu'une souris est utilisé, cet état correspond au moment où le clic commence et n'a pas encore été relâché.
:focus
, :focus-within
et :focus-visible
Si un élément peut être sélectionné (comme un <button>
), vous pouvez réagir à cet état avec la pseudo-classe :focus
.
Vous pouvez également réagir si un élément enfant de votre élément est sélectionné avec :focus-within
.
Les éléments pouvant être sélectionnés, comme les boutons, affichent un anneau de sélection lorsqu'ils sont sélectionnés, même lorsqu'ils sont cliqués. Dans ce type de situation, un développeur appliquera le CSS suivant :
button:focus {
outline: none;
}
Ce CSS supprime l'anneau de sélection par défaut du navigateur lorsqu'un élément est sélectionné, ce qui pose un problème d'accessibilité pour les utilisateurs qui naviguent sur une page Web à l'aide d'un clavier.
S'il n'y a pas de style de sélection, ils ne pourront pas savoir où se trouve actuellement la sélection lorsqu'ils utilisent la touche Tabulation.
Avec :focus-visible
, vous pouvez présenter un style de sélection lorsqu'un élément est sélectionné au clavier, tout en utilisant la règle outline: none
pour l'empêcher lorsqu'un dispositif de pointage interagit avec lui.
button:focus {
outline: none;
}
button:focus-visible {
outline: 1px solid black;
}
:target
La pseudo-classe :target
sélectionne un élément dont l'attribut id
correspond à un fragment d'URL.
Supposons que vous disposiez du code HTML suivant :
<article id="content">
<!-- ... -->
</article>
Vous pouvez associer des styles à cet élément lorsque l'URL contient #content
.
#content:target {
background: yellow;
}
Cela permet de mettre en évidence les zones qui ont pu être spécifiquement associées, comme le contenu principal d'un site Web, à l'aide d'un lien d'accès rapide.
États historiques
:link
La pseudo-classe :link
peut être appliquée à n'importe quel élément <a>
dont la valeur href
n'a pas encore été visitée.
:visited
Vous pouvez styliser un lien déjà visité par l'utilisateur à l'aide de la pseudo-classe :visited
.
Il s'agit de l'état opposé à :link
, mais vous disposez de moins de propriétés CSS pour des raisons de sécurité.
Vous ne pouvez appliquer un style qu'à color
, background-color
, border-color
, outline-color
et à la couleur des éléments SVG fill
et stroke
.
De l'importance de l'ordre des modificateurs
Si vous définissez un style :visited
, il peut être remplacé par une pseudo-classe de lien ayant au moins la même spécificité.
Pour cette raison, il est recommandé d'utiliser la règle LVHA pour styliser les liens avec des pseudo-classes dans un ordre particulier : :link
, :visited
, :hover
, :active
.
a:link {}
a:visited {}
a:hover {}
a:active {}
États du formulaire
Les pseudo-classes suivantes peuvent sélectionner des éléments de formulaire, dans les différents états dans lesquels ces éléments peuvent se trouver lors de l'interaction avec eux.
:disabled
et :enabled
Si un élément de formulaire, tel qu'un <button>
, est désactivé par le navigateur, vous pouvez vous raccrocher à cet état avec la pseudo-classe :disabled
.
La pseudo-classe :enabled
est disponible pour l'état opposé, bien que les éléments de formulaire soient également :enabled
par défaut. Vous n'aurez donc peut-être pas besoin de cette pseudo-classe.
:checked
et :indeterminate
La pseudo-classe :checked
est disponible lorsqu'un élément de formulaire compatible, tel qu'une case à cocher ou une case d'option, est coché.
L'état :checked
est un état binaire (vrai ou faux), mais les cases à cocher ont un état intermédiaire lorsqu'elles ne sont ni cochées ni décochées.
C'est ce qu'on appelle l'état :indeterminate
.
Par exemple, lorsque vous disposez d'un contrôle "Tout sélectionner" qui coche toutes les cases d'un groupe. Si l'utilisateur décoche l'une de ces cases, la case racine ne représente plus "toutes" les cases cochées et doit donc être placée dans un état indéterminé.
L'élément <progress>
possède également un état indéterminé qui peut être stylisé.
Un cas d'utilisation courant consiste à lui donner un aspect rayé pour indiquer que la quantité supplémentaire nécessaire est inconnue.
:placeholder-shown
Si un champ de formulaire comporte un attribut placeholder
et aucune valeur, la pseudo-classe :placeholder-shown
peut être utilisée pour associer des styles à cet état.
Dès qu'il y a du contenu dans le champ, qu'il soit placeholder
ou non, cet état ne s'applique plus.
États de validation
Vous pouvez répondre à la validation de formulaire HTML avec des pseudo-classes telles que :valid
, :invalid
et :in-range
.
Les pseudo-classes :valid
et :invalid
sont utiles dans des contextes tels qu'un champ d'adresse e-mail qui comporte un pattern
devant être mis en correspondance pour que le champ soit valide.
Cet état de valeur valide peut être affiché à l'utilisateur, ce qui l'aide à comprendre qu'il peut passer au champ suivant en toute sécurité.
La pseudo-classe :in-range
est disponible si une entrée comporte min
et max
, comme une entrée numérique and, et si la valeur se trouve dans ces limites.
Avec les formulaires HTML, vous pouvez déterminer qu'un champ est obligatoire avec l'attribut required
.
La pseudo-classe :required
sera disponible pour les champs obligatoires.
Les champs non obligatoires peuvent être sélectionnés avec la pseudo-classe :optional
.
Sélectionner des éléments par leur index, leur ordre et leur occurrence
Il existe un groupe de pseudo-classes qui sélectionnent des éléments en fonction de leur emplacement dans le document.
:first-child
et :last-child
Si vous souhaitez trouver le premier ou le dernier élément, vous pouvez utiliser :first-child
et :last-child
.
Ces pseudo-classes renvoient le premier ou le dernier élément d'un groupe d'éléments frères.
:only-child
Vous pouvez également sélectionner les éléments qui n'ont pas de frères et sœurs avec la pseudo-classe :only-child
.
:first-of-type
et :last-of-type
Vous pouvez sélectionner :first-of-type
et :last-of-type
, qui semblent faire la même chose que :first-child
et :last-child
, mais considérez ce code HTML :
<div class="my-parent">
<p>A paragraph</p>
<div>A div</div>
<div>Another div</div>
</div>
Et ce CSS :
.my-parent div:first-child {
color: red;
}
Aucun élément ne serait coloré en rouge, car le premier enfant est un paragraphe et non une div.
La pseudo-classe :first-of-type
est utile dans ce contexte.
.my-parent div:first-of-type {
color: red;
}
Même si le premier <div>
est le deuxième enfant, il est toujours le premier du type à l'intérieur de l'élément .my-parent
. Par conséquent, avec cette règle, il sera coloré en rouge.
:nth-child
et :nth-of-type
Vous n'êtes pas non plus limité aux premiers et derniers enfants, ni aux types.
Les pseudo-classes :nth-child
et :nth-of-type
vous permettent de spécifier un élément qui se trouve à un certain index.
L'indexation dans les sélecteurs CSS commence à 1.
Les pseudo-classes :nth-last-child()
et :nth-last-of-type()
comptent à partir de la fin, et non du début.
Vous pouvez également transmettre plus qu'un index à ces pseudo-classes.
Si vous souhaitez sélectionner tous les éléments pairs, vous pouvez utiliser :nth-child(even)
.
Vous pouvez également créer des sélecteurs plus complexes qui trouvent des éléments à intervalles réguliers à l'aide de la microsyntaxe An+B.
li:nth-child(3n+3) {
background: yellow;
}
Ce sélecteur sélectionne un élément sur trois, en commençant par le troisième.
Dans cette expression, n
est l'index, qui commence à zéro, et 3 (3n
) est le nombre par lequel vous multipliez cet index.
Imaginons que vous ayez sept éléments <li>
.
Le premier élément sélectionné est 3, car 3n+3
se traduit par (3 * 0) + 3
.
L'itération suivante sélectionnera l'élément 6, car n
est maintenant incrémenté à 1
, donc (3 * 1) + 3)
.
Cette expression fonctionne à la fois pour :nth-child
et :nth-of-type
.
:nth-child()
et :nth-last-child()
acceptent également une syntaxe "of S" qui vous permet de filtrer les correspondances avec un sélecteur, comme :nth-of-type()
. li:nth-of-type(even)
équivaut à :nth-child(even of li)
. Alors que :nth-of-type
ne vous permet de filtrer que par type d'élément (comme li
ou p
), la syntaxe "of S" vous permet de filtrer sur n'importe quel sélecteur.
Si vous avez un tableau, vous pouvez ajouter des bandes à une ligne sur deux. Bien que vous puissiez cibler une ligne sur deux avectr:nth-child(even)
, cela ne fonctionne pas si vous filtrez certaines lignes. Si vous implémentez le filtrage en appliquant l'attribut hidden
, vous pouvez ajouter of :not([hidden])
au sélecteur pour préfiltrer les éléments masqués avant de sélectionner les lignes paires.
tr:nth-child(even of :not([hidden])){
background: lightgrey;
}
Vous pouvez tester ce type de sélecteur sur cet outil de test nth-child ou cet outil de sélection de quantité.
:only-of-type
Enfin, vous pouvez trouver le seul élément d'un certain type dans un groupe de frères et sœurs avec :only-of-type
.
Cette option est utile si vous souhaitez sélectionner des listes ne comportant qu'un seul élément ou si vous souhaitez trouver le seul élément en gras d'un paragraphe.
Rechercher des éléments vides
Il peut parfois être utile d'identifier les éléments complètement vides. Il existe également une pseudo-classe pour cela.
:empty
Si un élément n'a pas d'enfants, la pseudo-classe :empty
s'applique à lui.
Toutefois, les enfants ne sont pas uniquement des éléments HTML ou des nœuds de texte. Ils peuvent également être des espaces blancs, ce qui peut être déroutant lorsque vous déboguez le code HTML suivant et que vous vous demandez pourquoi il ne fonctionne pas avec :empty
:
<div>
</div>
En effet, il y a des espaces entre les balises d'ouverture et de fermeture de <div>
, ce qui empêche :empty
de fonctionner.
La pseudo-classe :empty
peut être utile si vous avez peu de contrôle sur le code HTML et que vous souhaitez masquer les éléments vides, comme un éditeur de contenu WYSIWYG.
Ici, un éditeur a ajouté un paragraphe vide et isolé.
<article class="post">
<p>Donec ullamcorper nulla non metus auctor fringilla.</p>
<p></p>
<p>Curabitur blandit tempus porttitor.</p>
</article>
Avec :empty
, vous pouvez trouver et masquer ces informations.
.post :empty {
display: none;
}
Rechercher et exclure plusieurs éléments
Certaines pseudo-classes vous aident à écrire un code CSS plus compact.
:is()
Si vous souhaitez trouver tous les éléments enfants h2
, li
et img
dans un élément .post
, vous pouvez écrire une liste de sélecteurs comme celle-ci :
.post h2,
.post li,
.post img {
…
}
Avec la pseudo-classe :is()
, vous pouvez écrire une version plus compacte :
.post :is(h2, li, img) {
/* ... */
}
La pseudo-classe :is
est non seulement plus compacte qu'une liste de sélecteurs, mais elle est également plus tolérante.
Dans la plupart des cas, si une liste de sélecteurs contient une erreur ou un sélecteur non compatible, elle ne fonctionnera plus.
Si une erreur se produit dans les sélecteurs transmis dans une pseudo-classe :is
, le sélecteur non valide est ignoré, mais ceux qui sont valides sont utilisés.
:not()
Vous pouvez également exclure des éléments avec la pseudo-classe :not()
.
Par exemple, vous pouvez l'utiliser pour styliser tous les liens qui n'ont pas d'attribut class
.
a:not([class]) {
color: blue;
}
Une pseudo-classe :not
peut également vous aider à améliorer l'accessibilité.
Par exemple, un <img>
doit avoir un alt
, même s'il s'agit d'une valeur vide. Vous pouvez donc écrire une règle CSS qui ajoute un contour rouge épais aux images non valides :
img:not([alt]) {
outline: 10px red;
}
:has()
Que faire si vous souhaitez styliser des éléments en fonction de leur contenu ? Pour ce faire, vous pouvez utiliser la pseudo-classe :has()
. Par exemple, vous pouvez appliquer des styles aux boutons qui incluent des icônes.
button:has(svg) {
/* ... */
}
Dans sa configuration la plus élémentaire, comme dans l'exemple précédent, vous pouvez considérer :has()
comme un sélecteur parent. Vous pouvez également utiliser le sélecteur de parent correspondant avec d'autres sélecteurs pour cibler d'autres éléments.
form:has(input:valid) label {
font-weight: bold;
}
form:has(input:valid) label::after {
content: "✅";
}
Dans cet exemple, nous appliquons des styles à l'élément de libellé et au pseudo-élément label::after
lorsque l'entrée de formulaire possède une pseudo-classe valid
.
La pseudo-classe :has()
ne peut pas être imbriquée dans une autre :has()
, mais elle peut être combinée avec d'autres pseudo-classes.
:is(h1, h2, h3):has(a) {
/* ... */
}
La liste des sélecteurs est impitoyable. Si l'un d'eux n'est pas valide, toutes les règles de style seront ignorées.
.my-element:has(img, ::before) {
/* any styles here will be discarded since pseudo elements can't be included in the :has() selector list */
}
Vérifier que vous avez bien compris
Tester vos connaissances sur les pseudo-classes
Les pseudo-classes agissent comme si une classe avait été appliquée dynamiquement à un élément, tandis que les pseudo-éléments agissent sur un élément lui-même.
:
comme caractère clé distinctif dans le sélecteur.Parmi les propositions suivantes, laquelle est une pseudo-classe fonctionnelle ?
:is()
:target
()
pour indiquer qu'elles acceptent des paramètres.:empty
()
pour indiquer qu'elles acceptent des paramètres.:not()
Parmi les pseudo-classes suivantes, lesquelles sont dues à une interaction de l'utilisateur ?
:hover
:press
:squeeze
:target
:focus-within
Parmi les propositions suivantes, lesquelles sont des pseudo-classes d'état <form>
?
:enabled
:fresh
:indeterminate
:checked
:in-range
:loading
:valid