# Sélecteur de langue accessible : focus, ARIA et annonce du changement de langue

> Un audit d'accessibilité a pointé un sélecteur de langue invisible au clavier et muet pour un lecteur d'écran. Voici les corrections apportées.

- Auteur : Clément Hadrot
- Publié le : 2024-07-15
- Mis à jour le : 2024-07-15
- Catégorie : Multilingue
- URL : https://wpmoderne.dev.wordpress-developpement.fr/multilingue/selecteur-langue-accessible-aria/

## L’essentiel

- Un sélecteur uniquement cliquable à la souris exclut une partie des visiteurs
- Le changement de langue doit être annoncé explicitement à un lecteur d'écran
- L'attribut lang doit changer réellement, pas seulement l'affichage visuel

L'audit d'accessibilité commandé par un client public, soumis à des obligations réglementaires de conformité, a fait remonter un problème sur un composant qui semblait pourtant fonctionner sans souci en usage courant : le sélecteur de langue en haut de page. Visuellement, un drapeau par langue, cliquable, changeait bien la page affichée. Testé au clavier, sans souris, le composant devenait tout simplement impossible à atteindre : aucun des drapeaux ne recevait le focus lors de la navigation par tabulation.

Testé ensuite avec un lecteur d'écran, le problème s'est révélé plus profond encore : même quand un drapeau parvenait à être activé via un clic simulé, aucune annonce n'informait l'utilisateur du changement de langue effectué, et le contenu de la page restait annoncé dans la langue précédente par la synthèse vocale, produisant une lecture incompréhensible du nouveau contenu.

## Les quatre problèmes identifiés par l'audit

Le composant original reposait sur des éléments `<div>` cliquables via JavaScript, sans aucune sémantique native de lien ou de bouton. Ce choix technique, courant quand un composant est construit uniquement pour son rendu visuel, explique à lui seul l'essentiel des problèmes remontés.

- Absence de focus clavier : les éléments `div` ne sont pas nativement focalisables, contrairement aux liens `<a>` ou aux boutons `<button>`.
- Absence de rôle ARIA explicite, laissant un lecteur d'écran interpréter le composant comme du texte simple sans fonction interactive perceptible.
- Aucune annonce du changement de langue après activation, laissant l'utilisateur de lecteur d'écran sans confirmation de l'action réalisée.
- L'attribut `lang` de la balise `<html>` ne changeait pas après la navigation, ce qui faussait la prononciation du nouveau contenu par la synthèse vocale.

> L'essentiel à retenir : Un sélecteur uniquement cliquable à la souris exclut une partie des visiteurs ; Le changement de langue doit être annoncé explicitement à un lecteur d'écran ; L'attribut lang doit changer réellement, pas seulement l'affichage visuel

## La correction, élément par élément

### Rendre le composant nativement focalisable

La première correction a consisté à remplacer les `<div>` cliquables par des liens `<a href>` classiques, pointant vers l'URL réelle de chaque traduction. Ce changement, en apparence mineur, restaure gratuitement l'accessibilité au clavier : un lien natif reçoit le focus par tabulation et s'active avec la touche Entrée, sans code JavaScript supplémentaire.

```
<nav aria-label="Changer de langue">
  <ul>
    <li>
      <a href="/fr/" hreflang="fr" lang="fr" aria-current="true">
        Français
      </a>
    </li>
    <li>
      <a href="/en/" hreflang="en" lang="en">
        English
      </a>
    </li>
  </ul>
</nav>
```

Deux détails de ce balisage méritent attention : l'attribut `lang` posé sur chaque lien indique dans quelle langue le lien lui-même doit être prononcé (utile pour un lecteur d'écran qui lit « English » avec l'accent anglais plutôt que français), et `aria-current="true"` signale explicitement quelle langue est actuellement active, sans se reposer uniquement sur un style visuel de surlignage.

### Annoncer le changement de langue

Un changement de page classique (rechargement complet) est nativement annoncé par les lecteurs d'écran via le changement de titre de page. Le composant original utilisait cependant une navigation en partie asynchrone pour accélérer l'affichage, ce qui masquait ce changement de titre à la technologie d'assistance. La correction a consisté à forcer un rechargement complet de page lors du changement de langue, plus simple et plus fiable pour l'accessibilité qu'une navigation asynchrone mal instrumentée.

### Corriger l'attribut lang de la page

Sur un site utilisant Polylang ou WPML correctement configuré, la balise `<html lang="...">` devrait automatiquement refléter la langue de la page consultée. Le contrôle a révélé que cet attribut restait figé sur « fr » quelle que soit la langue affichée, un thème personnalisé ayant surchargé la fonction `language_attributes()` par une valeur codée en dur lors d'un développement antérieur.

```
// Correction : ne jamais coder en dur l'attribut lang
<html <?php language_attributes(); ?>>
```

## Ce que dit le WCAG sur ce composant précis

Le critère 3.1.2 (Langue d'un passage) des Web Content Accessibility Guidelines exige que tout changement de langue dans le contenu soit correctement identifié par le balisage. Le critère 4.1.2 (Nom, rôle et valeur) exige qu'un composant interactif expose son état correctement aux technologies d'assistance, ce que l'usage de liens natifs plutôt que de `div` cliquables satisfait directement sans code supplémentaire.

> Le réflexe le plus utile retenu de cet audit : avant d'ajouter de l'ARIA à un composant, vérifier si un élément HTML natif ne réglait pas déjà le problème sans aucun attribut supplémentaire.

## Vérifier le résultat

Après correction, le test au clavier confirme que chaque lien de langue reçoit le focus dans l'ordre attendu, avec un indicateur visuel de focus suffisamment contrasté. Le test avec un lecteur d'écran (NVDA a servi de référence pour cet audit) confirme que chaque lien est annoncé avec son rôle de lien, sa langue de prononciation correcte, et que le changement de page déclenche bien une nouvelle annonce du titre après navigation.

## En résumé

Un sélecteur de langue accessible ne demande, dans la majorité des cas, aucune prouesse technique : des liens natifs, un attribut `lang` correctement renseigné par élément, et une balise `html` qui reflète réellement la langue affichée suffisent à corriger l'essentiel des problèmes constatés lors de cet audit. La difficulté n'était pas technique, elle était dans le fait que personne n'avait testé ce composant sans souris avant la livraison initiale du site.
