Skip to main content

Chapitre 10 : Introduction aux pseudo-classes d'état utilisateur

Utilisation des pseudo-classes :hover, :active et :focus pour l'interactivité de base

L'un des aspects les plus gratifiants du développement front-end est de rendre une interface "vivante". Une page web statique peut sembler froide et confuse ; une interface qui réagit aux actions de l'utilisateur, en revanche, guide ce dernier et confirme que ses interactions sont prises en compte.

En CSS, cette interactivité est gérée principalement par les pseudo-classes d'état. Contrairement aux classes classiques que l'on ajoute manuellement via JavaScript, les pseudo-classes sont déclenchées automatiquement par le navigateur en fonction du comportement de l'utilisateur.

Les Pseudo-classes d'Interaction

1. Quoi

Une pseudo-classe est un mot-clé ajouté à un sélecteur CSS qui permet de cibler un élément non pas selon sa position dans le DOM ou son identifiant, mais selon son état actuel.

Nous nous concentrons ici sur les trois états fondamentaux de l'interaction utilisateur :

  • :hover : L'état de survol. Il s'active lorsque le pointeur (souris) se trouve au-dessus de l'élément.
  • :focus : L'état de concentration. Il s'active lorsque l'élément est sélectionné, généralement via la touche Tab du clavier ou un clic dans un champ de saisie.
  • :active : L'état d'activation. Il s'active au moment précis où l'élément est pressé (entre le clic de la souris et son relâchement).

2. Pourquoi

L'utilisation de ces états est cruciale pour deux raisons majeures :

L'Affordance et le Feedback Visuel L'affordance est la capacité d'un objet à suggérer sa propre utilisation. Un bouton qui change légèrement de couleur au survol indique clairement : "Je suis cliquable". Sans ce feedback, l'utilisateur peut hésiter ou douter de la fonctionnalité d'un élément.

L'Accessibilité (a11y) Le :focus est l'outil principal des utilisateurs naviguant au clavier. Si vous supprimez le contour par défaut du focus sans le remplacer par un style personnalisé, vous rendez votre site inutilisable pour les personnes malvoyantes ou celles utilisant des technologies d'assistance.

3. Comment

A. Syntaxe de base

La syntaxe consiste à coller la pseudo-classe au sélecteur sans espace.

/* Sélecteur { propriété: valeur; } */
.mon-bouton:hover {
background-color: blue;
}

B. Cas concret : Le bouton interactif professionnel

Dans un projet réel, on ne se contente pas de changer une couleur brutalement. On utilise des transitions pour rendre l'effet fluide et on respecte un ordre précis de déclaration pour éviter les conflits de priorité.

/* 1. État de base (Repos) */
.btn-primary {
display: inline-block;
padding: 12px 24px;
background-color: #3498db;
color: #ffffff;
border: 2px solid transparent;
border-radius: 6px;
cursor: pointer;
font-weight: 600;
text-decoration: none;

/* Transition: [propriété] [durée] [fonction de timing]
- all : s'applique à toutes les propriétés modifiées
- 0.2s : durée de l'animation (200 millisecondes)
- ease-in-out: démarre lentement, accélère, puis ralentit en fin d'animation */
transition: all 0.2s ease-in-out;
}

/* 2. État de survol (:hover)
On éclaircit ou assombrit légèrement la couleur */
.btn-primary:hover {
background-color: #2980b9;
transform: translateY(-2px); /* Petit effet de levée */
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}

/* 3. État de focus (:focus)
Indispensable pour l'accessibilité clavier */
.btn-primary:focus {
outline: none; /* On retire le contour navigateur par défaut */
border-color: #2c3e50;
box-shadow: 0 0 0 3px rgba(52, 152, 219, 0.4);
}

/* 4. État d'activation (:active)
Simule l'enfoncement physique du bouton */
.btn-primary:active {
background-color: #1c598a;
transform: translateY(0); /* Le bouton redescend */
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

C. Limitations et pièges

  1. Le tactile (Mobile) : Le :hover n'existe pas vraiment sur smartphone. Souvent, le navigateur simule un hover lors du premier clic, ce qui peut créer des comportements étranges (le bouton reste "survolé" même après le clic).
  2. L'ordre LVHA : Pour les liens (<a>), il existe une règle d'or pour l'ordre des pseudo-classes afin que les styles ne s'écrasent pas entre eux :
    • Link (:link)
    • Visited (:visited)
    • Hover (:hover)
    • Active (:active) Moyen mnémotechnique : "Love-Hate" ou "LVHA".

4. Zone de Danger

L'erreur classique : Supprimer le focus sans alternative

/* DANGER : Rend le site inaccessible au clavier */
*:focus {
outline: none;
}

La bonne pratique : Personnaliser le focus

/* CORRECT : On remplace le style par défaut par un style intégré au design */
.input-field:focus {
outline: none;
border: 2px solid #4A90E2;
box-shadow: 0 0 5px rgba(74, 144, 226, 0.5);
}

Cycle de vie des états utilisateur

Questions clés

Quelle est la différence fondamentale entre :hover et :active ?

Découvrir la réponse

Le :hover se déclenche dès que le curseur survole l'élément, sans interaction physique. Le :active ne se déclenche que pendant que l'utilisateur maintient le bouton de la souris enfoncé sur l'élément.

Pourquoi le :focus est-il considéré comme une priorité d'accessibilité ?

Découvrir la réponse

Parce que les utilisateurs qui ne peuvent pas utiliser de souris (handicaps moteurs, préférence clavier) naviguent de lien en lien via la touche Tab. Le style :focus est le seul indicateur visuel qui leur permet de savoir où ils se trouvent sur la page.

Que se passe-t-il si je déclare :hover après :active dans mon fichier CSS ?

Découvrir la réponse

En raison de la cascade CSS, si les deux états sont actifs simultanément (ce qui arrive lors d'un clic), le style déclaré en dernier gagnera. Si :hover est après :active, l'effet de "clic" visuel pourrait être masqué par le style de survol.

Le :hover fonctionne-t-il sur tous les éléments HTML ?

Découvrir la réponse

Techniquement oui, on peut mettre un :hover sur un <div> ou un <p>. Cependant, pour l'expérience utilisateur, il est recommandé de ne l'utiliser que sur des éléments interactifs (boutons, liens, inputs) pour ne pas confondre l'utilisateur.

Mise en pratique

Exercice 1 : Reproduction guidée

Objectif : Créer un lien de navigation simple qui change de couleur et se souligne au survol.

  • Créez un lien <a> avec la classe .nav-link.
  • État repos : couleur grise, pas de soulignement.
  • État survol : couleur bleue, soulignement apparent.
  • Ajoutez une transition de 0.3s.
Découvrir la solution commentée
.nav-link {
color: #666666;
text-decoration: none;
/* Transition pour éviter le changement brutal de couleur */
transition: color 0.3s ease;
}

.nav-link:hover {
color: #007bff;
text-decoration: underline;
}

Exercice 2 : Adaptation

Objectif : Transformer un champ de saisie (input) pour qu'il attire l'attention lors de la saisie.

  • Créez un input de type texte.
  • État repos : bordure grise fine.
  • État focus : bordure plus épaisse, couleur violette, et ajout d'une légère ombre portée (box-shadow) pour créer un effet de "halo".
Découvrir la solution commentée
.input-field {
border: 1px solid #ccc;
padding: 8px;
border-radius: 4px;
transition: all 0.2s ease;
}

.input-field:focus {
outline: none; /* On retire le contour bleu par défaut du navigateur */
border: 2px solid #8a2be2;
/* Le halo lumineux autour du champ */
box-shadow: 0 0 8px rgba(138, 43, 226, 0.3);
}

Exercice 3 : Conception

Objectif : Créer un "Bouton de Validation" complet respectant tout le cycle d'interaction.

  • Le bouton doit être vert au repos.
  • Il doit devenir vert foncé au survol.
  • Il doit afficher une bordure contrastée et un halo au focus.
  • Il doit "s'enfoncer" lors du clic (:active). Pour cela, vous aurez besoin de la propriété transform, qui permet d'appliquer des transformations géométriques à un élément :
    • scale(0.95) réduit sa taille à 95% de sa taille originale.
    • translateY(2px) le déplace légèrement vers le bas (2 pixels), simulant un enfoncement. Choisissez l'effet qui vous semble le plus naturel. Pour aller plus loin : MDN — transform.
Découvrir la solution commentée
.btn-submit {
background-color: #2ecc71;
color: white;
border: none;
padding: 10px 20px;
border-radius: 5px;
cursor: pointer;
font-size: 16px;
transition: all 0.1s ease; /* Transition très rapide pour le feedback tactile */
}

.btn-submit:hover {
background-color: #27ae60;
}

.btn-submit:focus {
outline: none;
box-shadow: 0 0 0 3px rgba(46, 204, 113, 0.5);
border: 1px solid #1e8449;
}

.btn-submit:active {
/* Effet de pression : on réduit légèrement la taille du bouton */
transform: scale(0.95);
background-color: #1e8449;
}