# Ajouter une région aria-live annonçant les résultats d’une recherche instantanée

> Une recherche instantanée met à jour la liste de résultats sans recharger la page, mais un lecteur d'écran ne le voit jamais sans une région aria-live bien réglée.

- Auteur : Clément Hadrot
- Publié le : 2021-01-21
- Mis à jour le : 2021-01-21
- Catégorie : Accessibilité
- URL : https://wpmoderne.dev.wordpress-developpement.fr/accessibilite/region-aria-live-resultats-recherche-instantanee/

## L’essentiel

- aria-live=polite pour ne pas couper la saisie
- Annoncer un compte de résultats, pas la liste entière
- Débattre l'annonce pendant la frappe

Un champ de recherche instantanée, qui filtre une liste de produits ou d'articles à chaque frappe sans recharger la page, est un excellent confort visuel. Pour un utilisateur voyant, le nombre de résultats affichés change sous ses yeux en temps réel. Pour un utilisateur de lecteur d'écran concentré sur son champ de saisie, rien de tout cela n'est perceptible : le curseur reste dans le champ, et la zone de résultats, ailleurs dans le DOM, change silencieusement. Sans région `aria-live`, cette mise à jour est tout simplement invisible pour lui.

La région `aria-live` permet de faire annoncer un changement de contenu sans déplacer le focus, condition indispensable ici puisque l'utilisateur doit pouvoir continuer à taper pendant que les résultats s'annoncent.

## Le HTML de la zone d'annonce

La bonne pratique consiste à créer une zone d'annonce dédiée, distincte de la liste de résultats elle-même, souvent masquée visuellement puisque le nombre de résultats est déjà visible à l'écran pour les autres utilisateurs :

```
<div id="recherche-statut" class="visually-hidden" aria-live="polite" aria-atomic="true"></div>
<ul id="resultats-recherche">
  <!-- résultats injectés dynamiquement -->
</ul>
```

`aria-atomic="true"` garantit que l'intégralité du contenu de la région est relue à chaque mise à jour, plutôt que seulement la partie modifiée — important ici car le texte annoncé change complètement à chaque frappe, ce n'est pas un ajout incrémental.

## Pourquoi polite et pas assertive

> L'essentiel à retenir : aria-live=polite pour ne pas couper la saisie ; Annoncer un compte de résultats, pas la liste entière ; Débattre l'annonce pendant la frappe

`aria-live="assertive"` interrompt immédiatement la lecture en cours, y compris celle de la propre saisie de l'utilisateur par certains lecteurs d'écran en mode d'écho des caractères. Sur une recherche instantanée, ce comportement est agressif et contre-productif : `polite` attend que le lecteur d'écran ait fini ce qu'il était en train d'annoncer avant de lire la mise à jour, ce qui laisse l'utilisateur taper sereinement.

## Ce qu'il faut annoncer, et ce qu'il ne faut surtout pas annoncer

Annoncer la liste complète des résultats à chaque frappe serait insupportable : à raison de plusieurs mises à jour par seconde pendant la frappe, le flux vocal deviendrait inaudible. La bonne pratique consiste à annoncer un simple compte, mis à jour avec un léger différé après la dernière frappe :

```
const champRecherche = document.getElementById('champ-recherche');
const statut = document.getElementById('recherche-statut');
let minuteur;

champRecherche.addEventListener('input', () => {
  clearTimeout(minuteur);
  minuteur = setTimeout(() => {
    const resultats = filtrerResultats(champRecherche.value);
    afficherResultats(resultats);
    statut.textContent = resultats.length === 0
      ? 'Aucun résultat trouvé'
      : resultats.length + ' résultat' + (resultats.length > 1 ? 's' : '') + ' trouvé' + (resultats.length > 1 ? 's' : '');
  }, 300);
});
```

Le délai de 300 millisecondes (un *debounce*) attend une pause dans la frappe avant de mettre à jour la région : suffisamment court pour rester réactif, suffisamment long pour ne pas déclencher une annonce à chaque caractère tapé.

## Le piège du contenu vide au premier chargement

Si la région `aria-live` est créée vide au chargement de la page puis remplie plus tard, certains lecteurs d'écran ne détectent pas le changement correctement selon le moment exact où la région a été insérée dans le DOM par rapport au moment où elle reçoit son premier contenu. La pratique la plus fiable consiste à insérer la région vide dès le chargement initial de la page (dans le HTML statique, pas injectée ensuite par script), puis à ne modifier que son contenu textuel par la suite.

## Vérification avec un vrai lecteur d'écran

Le test décisif se fait avec NVDA lancé, en tapant progressivement une requête dans le champ : l'annonce doit se déclencher une fois la frappe interrompue, mentionner un nombre cohérent, et ne jamais interrompre la frappe elle-même. Un test uniquement visuel, en observant la liste de résultats à l'écran, ne révèle jamais ce genre de défaut.

## En résumé

Une recherche instantanée sans région `aria-live` fonctionne parfaitement à la souris et reste invisible au clavier pour un utilisateur de lecteur d'écran. L'ajout d'une zone d'annonce discrète, avec un compte de résultats et un léger différé, referme cet écart pour un coût de développement minime.
