Les pseudo-classes CSS
bien plus que :hover

Pendant longtemps, la notion de pseudo classe se limitait à :hover. Pourtant, cette petite famille de sélecteurs est devenue particulièrement puissante avec l'évolution de CSS.

Une pseudo-classe permet de sélectionner un élément en fonction de son état, de sa position dans le document, de son contexte, de son comportement ou encore de certaines informations qui ne sont pas directement représentées dans le HTML.

Autrement dit, elle permet à CSS de prendre des décisions.

Le W3C définit d'ailleurs les pseudo-classes comme des sélecteurs permettant de cibler des éléments à partir d'informations qui peuvent être extérieures à l'arbre du document ou difficiles à exprimer avec les sélecteurs classiques. Elles peuvent notamment changer dynamiquement lorsque l'utilisateur interagit avec la page.

Une syntaxe extrêmement simple

button:hover {
background: black;
}

Ici, :hover ne crée aucun nouvel élément. Il indique simplement que la règle doit s'appliquer lorsque le bouton se trouve dans l'état « survolé ». C'est précisément ce qui distingue une pseudo-classe d'un pseudo-élément comme ::before ou ::after.

Le tableau des pseudo-classes CSS

Voici une référence regroupant les pseudo-classes CSS actuellement définies dans les spécifications et référencées par MDN. Certaines sont très courantes, d'autres sont spécialisées ou encore expérimentales.

 

Pseudo-classeFonctionExempleUtilisation courante
:activeÉlément actuellement activéa:activeBoutons, liens
:any-linkTout lien possédant hrefa:any-linkLiens
:autofillChamp rempli automatiquementinput:autofillFormulaires
:checkedCase ou option sélectionnéeinput:checkedCheckbox, radio
:defaultÉlément sélectionné par défautinput:defaultFormulaires
:definedÉlément défini:definedWeb Components
:dir()Direction du texte:dir(rtl)Multilingue
:disabledÉlément désactivébutton:disabledFormulaires
:emptyÉlément sans enfantdiv:emptyNettoyage conditionnel
:enabledÉlément activébutton:enabledFormulaires
:first-childPremier enfantli:first-childListes
:first-of-typePremier élément de son typep:first-of-typeStructure HTML
:focusÉlément ayant le focusinput:focusFormulaires
:focus-visibleFocus devant être visuellement indiquébutton:focus-visibleAccessibilité
:focus-withinÉlément contenant un élément focaliséform:focus-withinFormulaires
:fullscreenÉlément affiché en plein écranvideo:fullscreenMultimédia
:has()Sélection selon un descendant/contexte.card:has(img)Logique avancée
:hoverÉlément survoléa:hoverInteractions
:in-rangeValeur dans la plage autoriséeinput:in-rangeFormulaires
:indeterminateÉtat indéterminéinput:indeterminateCheckbox/progress
:invalidValeur invalideinput:invalidValidation
:is()Correspond à l'un des sélecteurs:is(h1,h2,h3)Simplification
:lang()Langue d'un élément:lang(fr)Internationalisation
:last-childDernier enfantli:last-childListes
:last-of-typeDernier élément de son typep:last-of-typeStructure HTML
:linkLien non encore visitéa:linkNavigation
:modalÉlément en état modaldialog:modalDialogues
:not()Exclut un sélecteurp:not(.intro)Exceptions
:nth-child()Enfant selon son rangli:nth-child(2)Grilles/listes
:nth-last-child()Enfant selon son rang depuis la finli:nth-last-child(2)Grilles/listes
:nth-of-type()Rang parmi un même typep:nth-of-type(2)Structure
:nth-last-of-type()Rang depuis la fin parmi un typep:nth-last-of-type(2)Structure
:only-childSeul enfantp:only-childStructure
:only-of-typeSeul élément de son typep:only-of-typeStructure
:openÉlément actuellement ouvertdetails:openInterfaces natives
:optionalChamp non obligatoireinput:optionalFormulaires
:out-of-rangeValeur hors plageinput:out-of-rangeFormulaires
:placeholder-shownPlaceholder actuellement visibleinput:placeholder-shownFormulaires
:playingMédia en lecturevideo:playingMultimédia
:pausedMédia en pausevideo:pausedMultimédia
:popover-openPopover ouvert[popover]:popover-openPopovers
:read-onlyChamp non modifiableinput:read-onlyFormulaires
:read-writeChamp modifiableinput:read-writeFormulaires
:requiredChamp obligatoireinput:requiredFormulaires
:rootRacine du document:rootVariables CSS
:scopeRacine du contexte courant:scopeSélections contextuelles
:seekingMédia en recherchevideo:seekingMultimédia
:stalledMédia bloqué pendant le chargementvideo:stalledMultimédia
:targetÉlément ciblé par l'URL#contact:targetAncres
:validValeur valideinput:validFormulaires
:visitedLien déjà visitéa:visitedNavigation
:where()Comme :is(), sans spécificité:where(h1,h2,h3)CSS maintenable
:user-invalidValeur invalide après interaction utilisateurinput:user-invalidFormulaires
:user-validValeur valide après interaction utilisateurinput:user-validFormulaires

 

À cette liste s'ajoutent des pseudo-classes plus spécialisées ou récentes, notamment celles liées aux transitions de vue, aux Web Components, aux popovers, au multimédia ou à certaines fonctionnalités expérimentales. MDN recense notamment :active-view-transition, :active-view-transition-type(), :has-slotted, :host(), :host-context(), :state() et plusieurs pseudo-classes encore expérimentales.

Les pseudo-classes structurelles

C'est probablement l'une des utilisations les plus intéressantes de CSS.

Prenons une liste :

<ul>
<li>Premier</li>
<li>Deuxième</li>
<li>Troisième</li>
<li>Quatrième</li>
</ul>

On peut cibler le premier et le dernier élément sans ajouter de classe HTML :

  • li:first-child {
    font-weight: bold;
    }
  • li:last-child {
    margin-bottom: 0;
    }

Mais :nth-child() va beaucoup plus loin :

li:nth-child(2) {
color: red;
}

Ou :

  • li:nth-child(odd) {
    background: #eee;
    }

Ou encore :

  • li:nth-child(3n) {
    margin-right: 0;
    }

Cette dernière notation permet de cibler les éléments 3, 6, 9, 12, etc.

Et CSS permet désormais d'affiner encore cette logique avec une sélection secondaire :

:nth-child(2n of .article)

Ce genre de sélecteur permet de traiter une structure HTML en fonction de sa position sans avoir à injecter artificiellement des classes dans le HTML. Le fonctionnement de :nth-child() et de sa syntaxe An+B est défini dans Selectors Level 4.

Les pseudo-classes fonctionnelles : une évolution importante

Certaines pseudo-classes acceptent des paramètres entre parenthèses.

Les trois plus importantes sont probablement :

  • :not()
  • :is()
  • :where()

Elle permet d'exprimer une exception :

button:not(.primary) {
opacity: .7;
}

On peut donc dire à CSS :

sélectionne tous les boutons sauf ceux qui possèdent .primary.

:is()

Elle permet de regrouper plusieurs sélecteurs :

:is(h1, h2, h3) {
font-family: sans-serif;
}

C'est beaucoup plus propre que :

h1,
h2,
h3 {
font-family: sans-serif;
}

Dans des sélecteurs complexes, l'intérêt devient encore plus évident.

:where()

:where() ressemble à :is(), mais avec une différence fondamentale : son contenu n'ajoute aucune spécificité au sélecteur.

C'est particulièrement intéressant lorsqu'on construit des feuilles CSS destinées à être facilement surchargées.

Le W3C définit précisément cette différence de spécificité entre :is() et :where().

Et puis il y a :has()

:has() est probablement l'une des pseudo-classes les plus intéressantes apparues dans CSS moderne.

Elle permet de sélectionner un élément en fonction de ce qu'il contient ou de ce qui se trouve dans son contexte.

Par exemple :

.card:has(img) {
padding-top: 0;
}

On peut lire cette règle comme :

sélectionne .card lorsqu'elle contient une image.

Autre exemple :

form:has(input:invalid) {
border: 1px solid red;
}

On peut donc modifier le formulaire parce qu'un de ses champs est invalide, sans ajouter de classe au <form> avec JavaScript.

C'est une évolution particulièrement importante : CSS peut désormais exprimer des relations qui nécessitaient auparavant du JavaScript ou une structure HTML spécialement préparée.

Le W3C définit :has() comme une pseudo-classe relationnelle permettant de sélectionner un élément lorsqu'un sélecteur relatif correspondant existe dans son contexte.

Sources et références

  • Mozilla Developer Network (MDN), Pseudo-classes — CSS
  • W3C, Selectors Level 4
  • Mozilla Developer Network (MDN), CSS Selectors
  • Mozilla Developer Network (MDN), Pseudo-classes and pseudo-elements

Dans une prochaine partie, nous irons plus loin avec les pseudo-classes avancées et leurs possibilités dans le CSS moderne.

Blog Webdesign & UX

Je conçois des sites internet...

Refonte graphique - Intégration WordPress - Migration Squarespace
Refonte – Migration WordPress
Epilhouse Guyanne
HJO BULTEN - conception graphique et développement Wordpress su mesure - webdesigner freelance
Conception graphique WordPress
HJO Bulten
Crazy CBD - webdesign wordpress - woo commerce - développeur et graphiste wordpress freelance
Boutique en ligne Woocommerce
Crazy CBD
site internet motorisé par Wordpress - version mobile
Conception site WordPressAK Peinture 38
Refonte graphique du site Wordpress Technipeintre
Refonte graphique WordPress
Technipeintre
Optimisation SEO et refonte graphique Wordpress - Ben CVC
Optimisation SEO
et refonte graphique WordPress
Ben CVC
Intégration graphique wordpress - développement sur mesure - cowool.co
Intégration charte graphique
développement WordPress sur mesure Cowool.co
Graphiste Wordpress - conception de site internet sur mesure
Conception graphique
& WordPress sur mesure
Ebor et Kobna

...et des films d'animation

TRUST MY NANNY - Animateur 2D, illustrateur & directeur artistique freelance
Web & Motion design
Trust my Nanny
INRIA- Animateur 2D illustrateur et animateur freelance - Video Rolling Stone
Vidéo d’animation
INRIA Espace Login
TRUST MY BOX - Animateur 2D, illustrateur & directeur artistique freelance
Web & Motion design
Trust my Box
Ethiki - Animateur 2D freelance
Vidéo motion design – animation
Ethiki
MOOC GRENOBLE #3 - Animateur 2D, illustrateur freelance
Vidéo d’animation
Université grenoble #3
Pattaya Restaurant - Animateur 2D, illustrateur, motion designer freelance
Vidéo d’animation
Restaurant Pattaya
On va négocier - Animateur 2D et illustrateur freelance
Animation 2D & Motion design
On va négocier
INRIA Rolling Stones - Animateur 2D, illustrateur & directeur artistique freelance
Vidéo d’animation
INRIA Rolling Stone

Webdesigner et animateur
de plus de 15 années d'expériences

Une note de 5 étoiles
sur les google reviews

Disponible, réponse
sous 24 heures maximum

Interlocuteur unique
à votre écoute

Des solutions
pour tous les budgets