# Menus déroulants accessibles au clavier : le piège que ratent les thèmes

> Un mega-menu magnifique à la souris peut devenir un mur infranchissable au clavier. Diagnostic d'un piège classique et corrections concrètes pour un menu WordPress vraiment navigable.

- Auteur : Clément Hadrot
- Publié le : 2021-05-14
- Mis à jour le : 2021-05-14
- Catégorie : Accessibilité
- URL : https://wpmoderne.dev.wordpress-developpement.fr/accessibilite/menus-deroulants-accessibles-clavier-wordpress/

## L’essentiel

- Les sous-menus doivent s'ouvrir sur focus, pas seulement sur survol
- Échap doit fermer un sous-menu ouvert
- Un menu invisible au clavier bloque tout le site

Un client avait fait développer un mega-menu à trois niveaux pour son site institutionnel, magnifique en apparence : icônes, aperçus d'images, colonnes bien réparties. Lors de la recette, un test simple a suffi à révéler le problème : en naviguant uniquement au clavier, impossible d'atteindre le troisième niveau. Les sous-menus ne s'ouvraient qu'au survol de la souris, un événement qu'aucune touche du clavier ne peut déclencher.

Ce défaut, très répandu, touche à la fois des thèmes premium et des développements sur mesure. Il illustre bien un principe central de l'accessibilité web : ce qui fonctionne parfaitement à la souris peut être totalement invisible pour qui navigue au clavier, que ce soit par choix, par nécessité motrice, ou parce qu'un lecteur d'écran est utilisé en parallèle.

## Pourquoi le survol seul ne suffit jamais

Un menu construit uniquement autour de l'événement CSS `:hover` repose sur une hypothèse fausse : que tous les visiteurs disposent d'un dispositif de pointage. Un utilisateur clavier passe d'un élément focusable à l'autre avec la touche Tab, sans jamais déclencher `:hover`. Si l'ouverture du sous-menu ne réagit pas à l'état `:focus` ou `:focus-within`, le sous-menu reste fermé et son contenu, invisible, inatteignable.

Le même problème touche les utilisateurs d'écrans tactiles, qui ne déclenchent pas non plus d'événement de survol persistant : un tap ouvre parfois le sous-menu, parfois suit directement le lien, selon l'implémentation, ce qui rend le comportement imprévisible pour tout le monde, pas seulement pour les utilisateurs de technologies d'assistance.

## Le comportement attendu d'un menu accessible

Le pattern ARIA Authoring Practices Guide (APG) pour les menus de navigation décrit un comportement précis, qu'il vaut mieux suivre à la lettre plutôt que d'improviser :

- Tab déplace le focus d'un élément de premier niveau à l'autre
- Entrée ou flèche bas ouvre le sous-menu de l'élément actuellement focalisé
- Les flèches haut et bas déplacent le focus entre les liens du sous-menu ouvert
- Échap referme le sous-menu et ramène le focus sur l'élément parent
- Un clic ou un focus en dehors du menu referme automatiquement tout sous-menu ouvert

> L'essentiel à retenir : Les sous-menus doivent s'ouvrir sur focus, pas seulement sur survol ; Échap doit fermer un sous-menu ouvert ; Un menu invisible au clavier bloque tout le site

## Une implémentation JavaScript minimale

Pas besoin d'une bibliothèque lourde pour corriger ce comportement. Un script court, ajouté au thème, suffit à gérer l'ouverture au focus et la fermeture à Échap :

```
document.querySelectorAll('.menu-item-has-children').forEach(function (item) {
  var toggle = item.querySelector('a');
  var submenu = item.querySelector('.sub-menu');

  item.addEventListener('focusin', function () {
    submenu.classList.add('is-open');
  });

  item.addEventListener('focusout', function (e) {
    if (!item.contains(e.relatedTarget)) {
      submenu.classList.remove('is-open');
    }
  });

  item.addEventListener('keydown', function (e) {
    if (e.key === 'Escape') {
      submenu.classList.remove('is-open');
      toggle.focus();
    }
  });
});
```

Ce script s'appuie sur `focusin` et `focusout`, deux événements qui, contrairement à `focus` et `blur`, remontent dans l'arbre DOM et se déclenchent correctement même quand le focus se déplace entre les liens d'un même sous-menu. Il reste minimal volontairement : dans un vrai projet, il faudra ajouter la gestion des flèches directionnelles et l'attribut `aria-expanded` mis à jour dynamiquement sur le bouton parent.

## Le rôle d'aria-expanded

L'attribut `aria-expanded`, positionné sur l'élément déclencheur d'un sous-menu, informe les lecteurs d'écran de l'état ouvert ou fermé, une information que l'apparence visuelle seule ne transmet pas aux technologies d'assistance. Sans cet attribut, un utilisateur de lecteur d'écran entend « menu, lien » sans savoir si un sous-menu existe ni s'il est déployé.

```
<button aria-expanded="false" aria-controls="sous-menu-services">
  Services
</button>
<ul id="sous-menu-services" class="sub-menu">
  ...
</ul>
```

## Tester le résultat sans outil complexe

Le test le plus fiable reste le plus simple : débrancher la souris, littéralement ou mentalement, et parcourir le menu entier à la touche Tab, du premier lien du site jusqu'au dernier élément du pied de page. Si un élément visible à l'écran ne peut être ni atteint, ni activé, ni refermé sans souris, le menu échoue, quelle que soit la qualité de son design.

> Un menu qui s'ouvre magnifiquement à la souris et jamais au clavier n'est pas un menu à moitié accessible. C'est un menu inaccessible qui, par chance, fonctionne pour une partie des visiteurs.

## En résumé

La navigation clavier des menus déroulants reste l'un des points les plus fréquemment ratés dans les thèmes WordPress, y compris chez des éditeurs reconnus. Le corriger ne demande ni refonte ni budget disproportionné : quelques dizaines de lignes de JavaScript, l'usage correct d'`aria-expanded`, et surtout un test systématique au clavier avant chaque mise en production suffisent à transformer un menu élégant en menu réellement utilisable par tous.
