Les pseudo-class en CSS

Posted 2024-03-15 by Sami Garcia ‐ 13 min read

On plonge dans les pseudo-class en CSS.

Pseudo-class

Une pseudo-class est un complément de sélecteur qui nous permet de sélectionner des éléments selon leurs états.

On peut par exemple sélectionner un élément lorsqu'il est survolé par la souris, selon la langue dans laquelle il est écrit, s'il est vide, si c'est un lien qui a été visité et bien plus encore.

Dans cet article, nous apprendrons à reconnaître une pseudo-class, et à utiliser les pseudo-class "basiques".

Nous aborderons toutes les pseudo-class dans différents articles classés par thèmes :

- les pseudo-class de bases (cet article)
- les pseudo-class enfant
- les pseudo-class de thème
- les pseudo-class de formulaire

La syntaxe

Une pseudo-class vient compléter un sélecteur. Prenons ici comme exemple un sélecteur de balise p sur lequel on ajoute une pseudo-class hover (qui sélectionne un élément lorsqu'il est survolé).

On obtiendra donc ce sélecteur : p:hover

Une pseudo-class vient donc compléter un sélecteur avec :pseudo-class

Lorsque la pseudo-class n'est pas précède d'un sélecteur comme ici :

:hover{
    color: red;
}

Cela revient à dire :

*:hover{
    color: red;
}
pseudo-class CSS tuto

En gros, l'absence de sélecteur avant une pseudo-class est interprété implicitement comme un sélecteur universel.

La pseudo-class est précédé de :, à ne pas confondre avec les pseudo-élément qui sont précédé de ::.

Pseudo-class VS Pseudo-élément

Une pseudo-class comme on l'a vue, sélectionne un élément en fonction de son état.

Un pseudo-élément, quant à lui, agit comme s'il ajoutait un élément HTML.

Prenons l'exemple du pseudo-élément: ::first-line

<p id="foo"> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. </p>
#foo::first-line{
    color: red;
}
pseudo-class CSS tuto

Ici on a donné à la première ligne de l’élément p la couleur rouge. Pourtant l’élément "première ligne" n'existe pas dans notre HTML (surtout que selon la taille de l’écran, la longueur de la première ligne est variable). On peut donc dire que le pseudo-élément ::first-line reviens à créer un span au sein de la balise p.

:root

La pseudo-class :root, permet de sélectionner un document html ou svg à sa racine. On peut se dire que cette pseudo-class ne correspond pas à la définition qu'on en a donné au début de cet article.

Pour mieux comprendre, il faut traduire :root comme : l'élément étant la racine du document.

On sélectionne donc un élément par son état; ici "étant la racine du document".

Alors pourquoi utiliser :root au lieu de directement sélectionner la balise html ?

En effet, les deux sélecteurs cibleront le même élément.

La grande différence ici, c'est la spécificité.

On sait par exemple qu'un sélecteur d'ID a une plus grande spécificité qu'un sélecteur de class :

<div class="foo" id="bar">
    
</div>
.foo{
    background-color: red;
}

#bar{
    background-color: blue;
}
pseudo-class CSS tuto

Ici on voit que la div a une background-color bleu, car la spécificité de l'id est plus forte.

Et bien c'est la même chose pour le sélecteur html et la pseudo-class :root:

html{
    background-color: blue;
}

:root{
    background-color: red;
}
pseudo-class CSS tuto

On voit que la background color est rouge, car la pseudo-class :root override le sélecteur html.

:hover

La pseudo-class :hover permet de sélectionner un élément lorsqu'il est survolé par la souris.

Voyons comment ça fonctionne :

<div class="one">
    <p>I'm the first élément</p>
</div>
<div class="two">
    <p>I'm the second élément</p>
</div>
.one{
   color: white; 
}

.two{
	background-color: blue;
}

div:hover{
    border: solid 1px white;
}

.one :hover{
    color: red;
}

.two:hover{
    background-color: red;
}
pseudo-class CSS tuto

On voit ici que les règle définis sur les sélecteurs ayant la pseudo-class :hover sont activé lorsque la souris survole l'élément.

On voit aussi que la spécificité de la pseudo-class :hover est très forte, car elle override les règle définis avant.

ATTENTION !

La spécificité de :hover est plus forte qu'un sélecteur seul comme on a pu le voir précédemment; div sera overright par div:hover quand la div sera survolé. Mais un sélecteur plus spécifique par exemple div p ne sera pas override par div:hover:

div p{
    color: white;
}

div:hover{
    color: red;
}
pseudo-class CSS tuto

:active

La pseudo-class :active sélectionne les éléments sur lesquels un clic avec la souris est effectué.

Elle est activée pendant le lapse de temp du clic :

<div>
    <p>Je suis dans une DIV</p>
</div>
<a href="cssami.com">cssami</a>
<button>Get Started</button>
div:active{
    background-color: red;
}
a:active{
    font-size: 20px;
}
button:active{
    box-shadow: 5px 5px 5px blue;
}
pseudo-class CSS tuto

Tout comme le :hover sa spécificité est élevé, elle override donc les règle définis sur ces mêmes éléments, mais n'override pas les règles définis sur des sélecteurs plus précis.

:empty

La pseudo-class :empty sélectionne les éléments vides.

Elle peut s'avérer très pratique lorsque par exemple on applique un style a tous les p, on ne veut pas forcément que ce style soit appliqué aux éléments p vides, alors on peut tout simplement faire ça :

<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
<p></p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
p{
    padding: 30px;
    background-color: grey;
}
pseudo-class CSS tuto
p:empty{
    display: none;
}
pseudo-class CSS tuto

ATTENTION !

La pseudo-class :empty ne sélectionne que les éléments complètement vides, ou contenant un commentaire.

Un élément contenant un espace ne sera pas sélectionné :

<p> </p> <!-- je ne suis pas sélectionné -->
<p></p><!-- je suis sélectionné -->
<p><!-- je suis sélectionné --></p>
<p> <!-- je ne suis pas sélectionné à cause des espaces --> </p>

Deuxième précision ; L'utilisation de la pseudo-class :empty sur un élément input ne fonctionnera pas comme on pourrais l'imaginer.

En effet, on pourrait penser qu'en définissant une règle avec le sélecteur :empty sur un input, lorsqu'on entrera du texte dans ce même input, la règle ne sera plus respectée, comme cela :

input:empty{
    color: red;
}

input{
    color: blue;
}
pseudo-class CSS tuto

Cependant cela ne fonctionne pas, car l'input dans l'html reste vide malgré que l'utilisateur ait entré du contenu. Pour cela on utilisera la pseudo-class :placeholder-shown dont on parlera dans l'article les pseudo-class de formulaire.

:lang

La pseudo-class :lang sélectionne un élément en fonction de la langue dans laquelle il est écrit.

Evidemment, le navigateur ne détecte pas automatiquement la langue dans laquelle est écrit un élément.

Le navigateur se base sur la langue indiquer dans les métadonnées du site, et sur les attributs lang définis sur les éléments.

Prenons cet exemple :

<!DOCTYPE html>
<html lang="en">
  <body>
	<p>Hey guys! this website is in English</p>
    <p lang="fr">Salut les gars ! Ce site est en Anglais, mais je trduit pour les francophones </p>
    <p lang="es">Hola chicos ! Esta pagina web es en Ingles pero hago la traducion para mis amigos Españoles</p>
  </body>
</html>
p{
    color: green;
}
p:lang(en){
    color: white;
}

p:lang(fr){
    color: blue;
}

p:lang(es){
    color: red;
}
pseudo-class CSS tuto

On voit que les balise p n'ayant pas d'attribut lang sont en blanc, car la langue du site est définie sur anglais.

La pseudo-class :link permet de sélectionner un lien n'ayant pas été visité :

<a href="cssami.com">CSSami</a>
<a href="layoutcss.com">LayoutCSS</a>
a:link{
    color: green;
}
pseudo-class CSS tuto

On voit qu'une fois le lien visité, les règles définies par le sélecteur a:link ne sont plus appliqués.

:visited

La pseudo-class :visited quant à elle, permet de sélectionner les liens visités.

<a href="cssami.com">CSSami</a>
<a href="layoutcss.com">LayoutCSS</a> <!-- ce lien a été visité -->
a:visited{
    color: red;
}
pseudo-class CSS tuto

:target

La pseudo-class :target permet de sélectionner un élément unique dont l'id est contenu dans l'URI.

Bon, ça c'est la définition qui toute seul veut un peut rien dire, mais pas de panique, on va rendre tout ça un peu plus claire.

Déjà pour commencer, il faut savoir qu'en HTML, dans le href d'une balise a, on peut indiquer l'ID d'un élément, et lorsqu'on cliquera sur ce lien, la page scrollera jusqu'à cet élément:

<a href="#mon-image">découvre l'image</a>
<p>
  Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.  
</p>
<img alt="pseudo-class CSS tuto" src="mon-image.png" id="mon-image">
<p>
  Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.  
</p>
pseudo-class CSS tuto

Comme on peut le voir, notre lien renvoi bien sur notre image.

Mais le plus important, est que notre URL qui avant de cliquer sur le lien était: https://cssami.com/mon-article/, est devenu: https://cssami.com/mon-article/#mon-image

On voit donc qu'à la fin de notre url est venu s'ajouter #mon-image (l'ID de notre image).

La pseudo-class :target sélectionne donc l'élément dont l'ID figure à la fin de l'URI après le #.

On sait donc que l'élément a été 'target' par un lien car son id apparait dans l'URI.

Voyons maintenant comment ça marche en reprenant l'exemple d'HTML précédant:

#mon-image:target{
	border: solid 3px red;
	border-radius: 10px;
}
pseudo-class CSS tuto

On voit donc que notre élément recoit les règles définis par le sélecteur #mon-image:target qu'une fois que son ID apparait dans l'uri.

Bien sûre, le sélecteur précédant la pseudo-class :target ne sera pas obligatoirement un sélecteur d'id:

<a href="#img1">img1</a>
<a href="#img2">img2</a>
<a href="#img3">img3</a>
<a href="#img4">img4</a>
<a href="#img5">img5</a>
<img alt="pseudo-class CSS tuto" src="img1" id="img1">
<img alt="pseudo-class CSS tuto" src="img2" id="img2">
<img alt="pseudo-class CSS tuto" src="img3" id="img3">
<img alt="pseudo-class CSS tuto" src="img4" id="img4">
<img alt="pseudo-class CSS tuto" src="img5" id="img5">
img:target{
    border-radius: 10px;
    border: 2px red solid;
}
pseudo-class CSS tuto

Ici on dit : l'image qui est target (dont l'ID apparait dans l'URI) aura un border-radius de 10px et un border rouge de 2px

Pseudo-class de logique

J'appelle "pseudo-class de logique", les pseudo-class fonctionnent plus ou moins comme des if dans les langages de programmations.

Ces pseudo-class seront déclencher si un de leurs arguments renvoient true ou false en fonction de ce qui est définis.

Ces pseudo-élément permettent de raccourcir drastiquement notre CSS quand on s'attaque à des règles complexes.

:is

La pseudo-class :is() nous permet de sélectionner tous les éléments retournant true à un de ses attribut :

<div>
    <h1>Salut les gars !</h1>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
    <h2>Premiere partie</h2>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
</div>
<h1>Fin</h1>
:is(h1, h2, p){
    color: white;
}
pseudo-class CSS tuto

On voit donc que les élément h1, h2 et p ont été sélectionnés. Et tu te demandes surement pourquoi pas simplement faire :

h1, 
h2, 
p{
    color: blue;
}

Et tu as bien raison ! C'est plus concis, et on obtient le même résultat.

En fait, le gros intérêt de la pseudo-class :is() c'est de rendre les sélecteurs complexe (avec des combinateurs ou d'autres pseudo-class), beaucoup plus concis et simples :

div h1,
div h2,
div p{
    color: blue;
}

div h1:hover,
div h2:hover,
div p:hover,
div h1:active,
div h2:active,
div p:active{
    color: red;
}

Deviendras grâce à la pseudo-class :is():

div :is(h1, h2, p){
    color: white;
}

div :is(h1, h2, p):is(:hover, :active){
    color: red;
}

:not

La pseudo-class :not() permet de sélectionner tous les éléments ne correspondant pas à ses arguments.

Par exemple le sélecteur div:not(.foo, #bar) peut se traduire : "toutes les div, sauf celles qui ont la class foo, ou l'id bar".

<div>
    <h1>Salut les gars !</h1>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
    <h2>Premiere partie</h2>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
</div>
div :not(p){
    color: black;
}
pseudo-class CSS tuto

On voit donc que tous les éléments contenus dans la div sont en noir, sauf les éléments p.

:where

La pseudo-class :where() fonctionne comme la pseudo-class :is().

Alors pourquoi on en a deux ?

La grande différence entre :where et :is est la spécificité. En effet la pseudo-class:where a une spécificité très basse, et la pseudo-class :is a la spécificité des sélecteurs qu'il contient.

Une pseudo-class :where nous donnera donc la possibilité d'être override:

<div>
    <h1>Salut les gars !</h1>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
    <h2>Premiere partie</h2>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
</div>
div :where(h1, h2, p){
    color: black;
}

h2{
    color: red;
}
pseudo-class CSS tuto

On voit ici que le h2 est bien rouge. Alors qu'avec une pseudo-class :is:

div :is(h1, h2, p){
    color: blue;
}

h2{
    color: red;
}
pseudo-class CSS tuto

Le sélecteur h2 est override.