Concepts

Piège de focus

Technique qui confine le focus clavier à l'intérieur d'une boîte de dialogue modale pendant son ouverture — empêchant Tab de s'échapper vers le document sous-jacent, et restituant le focus à l'élément déclencheur à la fermeture.

Un piège de focus est une contrainte délibérée sur la navigation au clavier : pendant qu’une boîte de dialogue modale est ouverte, Tab ne parcourt que les éléments pouvant recevoir le focus à l’intérieur de cette boîte. Shift+Tab fait l’inverse. L’utilisateur ne peut pas sortir par Tab vers la page (visuellement masquée) derrière la modale avant de la fermer explicitement.

Le piège de focus est obligatoire pour les boîtes de dialogue modales accessibles. Sans lui, les utilisateurs au clavier et les utilisateurs de lecteurs d’écran se retrouvent sur du contenu de page invisible qu’ils ne voient pas et dont ils ne peuvent pas s’échapper.

Pourquoi c’est nécessaire

Une boîte de dialogue modale est présentée visuellement comme une couche au-dessus de la page. L’intention — sans ambiguïté — est que l’utilisateur interagisse avec la modale jusqu’à la fin, puis revienne à la page. Pour les utilisateurs de souris, c’est intuitif : cliquer en dehors de la modale ne fait rien (ou la ferme) ; cliquer à l’intérieur atteint les contrôles de la modale.

Sans piège de focus, les utilisateurs au clavier obtiennent une expérience incohérente :

  1. La modale s’ouvre. Le focus se déplace vers (ou devrait se déplacer vers) le premier élément pouvant recevoir le focus à l’intérieur.
  2. L’utilisateur appuie sur Tab. Le focus se déplace vers l’élément suivant à l’intérieur de la modale.
  3. L’utilisateur continue d’appuyer sur Tab. Le focus atteint finalement le dernier élément pouvant recevoir le focus à l’intérieur de la modale.
  4. Un Tab de plus. Sans piège, le focus saute vers l’élément pouvant recevoir le focus suivant dans le document — quelque part derrière la modale, invisible pour l’utilisateur.

Le seul signal que l’utilisateur reçoit est la disparition de l’indicateur de focus de la modale. Il n’a aucune idée de l’endroit où se trouve son focus.

Le modèle de modale complet

Une modale accessible complète inclut :

  1. Le focus entre dans la modale à son ouverture — généralement vers le premier élément pouvant recevoir le focus ou vers le titre de la modale (si le titre possède tabindex="-1" pour un focus programmatique).
  2. Le focus est piégé à l’intérieur de la modale : Tab depuis le dernier élément revient au premier ; Shift+Tab depuis le premier revient au dernier.
  3. Echap ferme la modale et restitue le focus à l’élément déclencheur qui l’a ouverte (pas au corps du document).
  4. Un clic en dehors de la modale la ferme — comportement optionnel ; toutes les modales ne le font pas, mais si c’est le cas, le focus doit rester piégé pendant l’ouverture.
  5. role="dialog" plus aria-modal="true" sur l’élément modal, avec aria-labelledby pointant vers le titre de la modale.

Implémentations

La bibliothèque la plus citée est focus-trap (npm : focus-trap, focus-trap-react, focus-trap-vue) — légère, sans dépendances, gère tous les cas limites (ignorer les éléments invisibles, s’intégrer avec inert, restituer le focus à la fermeture).

Le primitif navigateur moderne est <dialog> avec dialog.showModal(), qui piège automatiquement le focus et gère Echap. La compatibilité navigateur est désormais suffisamment solide pour l’utiliser comme base.

Anti-modèle : le « piège qui ne libère pas »

Un piège de focus doit se libérer à la fermeture de la modale. Le bug d’implémentation le plus courant est d’oublier de restituer le focus à l’élément déclencheur d’origine — le focus se retrouve alors sur le corps du document, que les lecteurs d’écran annoncent comme rien. L’utilisateur est plongé dans le silence et doit recommencer à tabuler depuis le haut de la page.