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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
: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;
}
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;
}
p:empty{
display: none;
}
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;
}
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;
}
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.
:link
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;
}
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;
}
: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>
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
Le sélecteur h2
est override.