# Un focus qui saute au mauvais endroit après la fermeture d’une fenêtre modale

> Après la fermeture d'une fenêtre modale, le focus clavier atterrit parfois n'importe où sur la page, voire disparaît. Diagnostic complet d'un bug très gênant pour les utilisateurs au clavier.

- Auteur : Clément Hadrot
- Publié le : 2021-03-25
- Mis à jour le : 2021-03-25
- Catégorie : Accessibilité
- URL : https://wpmoderne.dev.wordpress-developpement.fr/accessibilite/focus-saute-mauvais-endroit-fermeture-modale/

## L’essentiel

- Le focus revient au body plutôt qu'au bouton d'ouverture
- La cause vient souvent de la suppression du DOM avant la restauration
- Toujours stocker une référence à l'élément déclencheur

Le symptôme remonté par un testeur au clavier était précis : « après avoir fermé la popup de newsletter, j'appuie sur Tab et je me retrouve tout en haut de la page, avant le logo ». Un défaut discret à la souris, où l'on ne remarque jamais où atterrit le focus, mais franchement pénible au clavier, puisqu'il faut alors retraverser tout le menu de navigation pour revenir là où on se trouvait avant l'ouverture de la fenêtre.

Ce défaut porte un nom dans les référentiels d'accessibilité : la perte de focus, ou focus mal repositionné. Il touche presque toutes les fenêtres modales codées sans suivre le motif ARIA officiel, et se corrige toujours de la même manière une fois la cause identifiée.

## Symptôme observé pas à pas

En reproduisant le scénario : ouverture de la modale par un clic sur un bouton « S'inscrire à la newsletter », fermeture par la croix ou par la touche Échap, puis appui sur Tab. Le focus se retrouve tantôt sur le premier lien du menu, tantôt totalement invisible, comme si le navigateur avait remis le focus sur `<body>`, qui n'est normalement pas un élément focusable.

## Diagnostic : où va vraiment le focus quand un élément disparaît

> L'essentiel à retenir : Le focus revient au body plutôt qu'au bouton d'ouverture ; La cause vient souvent de la suppression du DOM avant la restauration ; Toujours stocker une référence à l'élément déclencheur

La règle du navigateur est simple et rarement documentée dans les tutoriels de modales : quand l'élément qui a le focus est retiré du DOM (ou masqué avec `display: none`), le focus retombe automatiquement sur `<body>`. Si la fenêtre modale avait le focus au moment de sa fermeture — ce qui est le cas normal, puisque le focus doit être piégé à l'intérieur pendant qu'elle est ouverte — et que le code de fermeture se contente de masquer la modale sans jamais restaurer explicitement le focus ailleurs, alors le focus part sur `<body>`, d'où le comportement observé au Tab suivant, qui repart du tout début du DOM.

```
// Code fautif : ferme la modale sans restaurer le focus
function fermerModale() {
  modale.classList.add('masquee');
  modale.setAttribute('aria-hidden', 'true');
}
```

## Le correctif : mémoriser puis restaurer le déclencheur

La correction demande de conserver une référence à l'élément qui avait le focus avant l'ouverture de la modale — presque toujours le bouton qui l'a déclenchée — et de lui redonner explicitement le focus à la fermeture :

```
let declencheur = null;

function ouvrirModale(bouton) {
  declencheur = bouton;
  modale.classList.remove('masquee');
  modale.setAttribute('aria-hidden', 'false');
  modale.querySelector('button, [href], input').focus();
}

function fermerModale() {
  modale.classList.add('masquee');
  modale.setAttribute('aria-hidden', 'true');
  if (declencheur) {
    declencheur.focus();
  }
}
```

Ce simple appel à `declencheur.focus()` ramène l'utilisateur exactement là où il se trouvait avant l'ouverture, ce qui correspond à ce qu'un utilisateur voyant vit implicitement : la modale disparaît, l'attention visuelle revient naturellement à l'endroit où elle se trouvait avant l'interruption.

## Le piège de la fermeture par Échap

Un oubli fréquent : la fonction de fermeture appelée au clic sur la croix restaure bien le focus, mais celle appelée sur la touche Échap est une fonction différente, ajoutée plus tard par un autre développeur, qui ne fait pas le même appel. Vérifier que tous les chemins de fermeture — croix, Échap, clic en dehors de la modale — passent par la même fonction unique évite ce genre d'écart silencieux.

## Vérification

Le test de non-régression tient en quatre étapes reproductibles : ouvrir la modale au clavier, la fermer par chacun des trois moyens disponibles, et vérifier à chaque fois qu'un appui sur Tab suivant atterrit sur l'élément qui suit logiquement le bouton d'ouverture dans la page, jamais sur `<body>` ni sur le tout premier élément focusable du document.

## En résumé

Une fenêtre modale bien fermée doit rendre le focus exactement là où il se trouvait avant son ouverture. Ce comportement ne s'obtient jamais par hasard : il demande de mémoriser explicitement l'élément déclencheur à l'ouverture et de lui redonner le focus à la fermeture, sur chacun des chemins qui permettent de fermer la fenêtre.
