Une modal mal faite est une porte fermée pour un utilisateur clavier : le focus reste derrière, ESC ne fait rien, et le lecteur d'écran continue de lire la page d'en dessous. Les 5 règles ci-dessous sont l'application directe du pattern "dialog" de l'ARIA Authoring Practices Guide — le standard de référence.

Les 5 règles non négociables

  1. 01À l'ouverture, le focus passe sur le premier élément focusable de la modal (ou sur la modal elle-même)
  2. 02Le focus est piégé dans la modal : Tab et Shift+Tab tournent en boucle dedans, sans repartir dans la page
  3. 03La touche ESC ferme la modal
  4. 04À la fermeture, le focus revient sur l'élément qui a ouvert la modal
  5. 05Les attributs `role="dialog"` (ou "alertdialog"), `aria-modal="true"` et `aria-labelledby` pointant vers le titre sont présents

Le squelette HTML correct

<div role="dialog" aria-modal="true" aria-labelledby="dlg-title">
  <h2 id="dlg-title">Confirmer la commande</h2>
  <button aria-label="Fermer">x</button>
  <!-- contenu -->
</div>

L'`aria-labelledby` donne un nom à la boîte de dialogue : le lecteur d'écran annonce "Confirmer la commande, dialogue" à l'ouverture. Le bouton de fermeture (souvent une croix) doit porter un `aria-label="Fermer"`, sinon il est annoncé comme un "bouton" sans intitulé.

Le focus trap, là où tout se joue

Pendant que la modal est ouverte, le reste de la page doit être inerte : ni focusable, ni lu. C'est le rôle du piégeage de focus, et idéalement de l'attribut `inert` posé sur le contenu de fond. Sans lui, l'utilisateur clavier peut "sortir" de la modal sans la voir et se perdre dans une page qu'il ne devrait pas atteindre.

// Composants prêts à l’emploi

Reka UI (utilisé par ComplAudit), Radix Vue, Headless UI : tous ces kits implémentent un Dialog conforme (focus, ESC, ARIA, inert) déjà testé. Écrire sa propre modal à la main en 2026, c'est s'exposer à rater au moins 2 des 5 règles — presque toujours le retour de focus et le trap.

Tester en 1 minute

  1. 01Ouvrez la modal au clavier (Enter sur le déclencheur)
  2. 02Vérifiez que le focus est bien entré dedans
  3. 03Tabulez plusieurs fois : le focus doit rester piégé dans la modal
  4. 04Pressez ESC : elle doit se fermer
  5. 05Vérifiez que le focus est revenu sur le bouton déclencheur

Questions fréquentes

dialog ou alertdialog ?

`role="dialog"` pour une boîte standard (formulaire, information). `role="alertdialog"` pour une interruption critique qui exige une décision immédiate ("Supprimer définitivement ?"). L'alertdialog est annoncé plus fermement par le lecteur d'écran.

La balise <dialog> HTML native suffit-elle ?

L'élément `<dialog>` avec `showModal()` gère nativement le focus trap, la touche ESC et l'inertie du fond. C'est une excellente base moderne, à condition de soigner le `aria-labelledby` et le retour de focus à la fermeture. Son support navigateur est désormais large.

Faut-il bloquer le scroll de la page derrière ?

Oui : c'est une bonne pratique d'UX et d'accessibilité. Le fond ne doit pas défiler pendant que la modal est ouverte, sous peine de désorienter l'utilisateur.

Vérifier que vos modals gèrent bien le focus et le clavier :

→ Lancer un audit