WCAG AA Votre équipe + Prestataire Moyen

Peut-on utiliser toutes les fonctionnalités interactives de votre site en utilisant uniquement le clavier ?

Critère officiel 7.3 — Chaque script est-il contrôlable par le clavier et par tout dispositif de pointage (hors cas particuliers) ?

Pourquoi c'est important

Les personnes qui ne peuvent pas utiliser une souris — handicap moteur, paralysie, utilisation d'un commutateur — naviguent exclusivement au clavier. Si un menu, une fenêtre modale ou un bouton n'est pas atteignable par Tab ou activable par Entrée, ces personnes sont bloquées et ne peuvent pas accomplir leur démarche.

Exemples concrets

Ce qui est conforme

La fenêtre modale « Inscription à la newsletter » s'ouvre avec Entrée, le focus reste à l'intérieur pendant qu'elle est ouverte, et Échap la ferme en renvoyant le focus sur le bouton d'ouverture. Navigation entièrement possible sans souris.

Ce qui pose problème

Le même formulaire modal ne peut être fermé qu'en cliquant sur la croix avec la souris. Un utilisateur au clavier se retrouve piégé dans la fenêtre : Tab ne fait que boucler sur les champs internes sans possibilité de sortir.

Comment agir

Testez vos pages principales en ignorant la souris. Utilisez uniquement Tab (avancer), Maj+Tab (reculer), Entrée (activer), Échap (fermer les fenêtres modales). Si le focus disparaît ou si vous êtes bloqué quelque part, notez l'élément et signalez-le à votre prestataire. Ce test prend 5 minutes par page et révèle les problèmes les plus bloquants.

Règles clés

  • Tout élément interactif doit être focusable : utiliser un élément natif (<button>, <a>) ou ajouter tabindex="0" sur un élément custom.
  • Les éléments avec role="button" doivent répondre à Enter ET Espace : ajouter un listener keydown explicite.
  • Respecter les conventions de navigation clavier APG pour chaque type de composant : flèches pour les onglets et menus, Échap pour fermer, Home/End pour aller au premier/dernier élément.
  • Si une fonctionnalité requiert un geste complexe (drag & drop, pinch to zoom), proposer une alternative clavier équivalente.
  • Chaque élément interactif doit avoir un indicateur de focus visible (critère 10.7).

Erreurs fréquentes

  • Déclencheurs sur des <div> ou <span> sans tabindex="0" : non focusables au clavier
  • Événements uniquement sur onclick sans équivalent onkeydown/onkeyup pour Enter et Espace
  • Composant focusable mais dont les interactions internes (flèches, Échap) ne sont pas gérées
  • Carrousel avec boutons Précédent/Suivant non focusables ou manquants
  • Datepicker ou sélecteur de date uniquement accessible à la souris
  • Drag & drop sans alternative clavier
  • Infobulle (tooltip) affichée via un script JavaScript uniquement au survol souris, sans mécanisme d'affichage au focus clavier : non-conformité 7.3 si l'affichage est piloté par du JavaScript. À distinguer du cas CSS (non-conformité 10.14). Si l'infobulle ne contient que du texte sans élément interactif, la solution privilégiée est aria-describedby sur le déclencheur plutôt que de rendre l'infobulle elle-même focusable.
  • Liens à l'intérieur d'un tooltip : fonctionnellement inaccessibles au clavier. Le déclencheur doit avoir le focus pour que la description apparaisse ; déplacer le focus vers le lien interne rompt la connexion aria-describedby et ferme le tooltip. aria-describedby est conçu pour du texte brut uniquement. Si des liens sont nécessaires, utiliser une dialog non-modale déclenchée au clic/Entrée selon le pattern ARIA Authoring Practices Guide.
  • Composant ou liste d'éléments focusables disposés avec CSS Grid Lanes sans vérification de l'ordre de tabulation : l'ordre de focus suit le DOM tandis que l'ordre visuel suit la logique de remplissage des colonnes par hauteur croissante. Un utilisateur clavier peut ainsi se retrouver à naviguer de la colonne 2 à la colonne 3 puis à la colonne 1 de façon imprévisible, violant l'attente d'un déplacement cohérent du focus (WCAG 2.4.3). Contournement temporaire : utiliser le hack CSS '.grid-lanes:has(:focus-visible) { display: grid; }' pour basculer en grille ordinaire dès qu'un élément reçoit le focus, mais cette approche modifie visuellement la mise en page à la prise de focus et reste expérimentale.

Exemples de code

div cliquable non focusable

✗ Non conforme
<div class="btn-custom" onclick="soumettre()">Valider</div>

Une <div> n'est pas dans l'ordre de tabulation et ne reçoit pas les événements clavier. Inaccessible au clavier.

élément natif ou tabindex + keydown

✓ Conforme
<!-- Option 1 : élément natif (toujours préférable) -->
<button type="button" onclick="soumettre()">Valider</button>

<!-- Option 2 : si le <div> est inévitable (composant legacy) -->
<div
  role="button"
  tabindex="0"
  onclick="soumettre()"
  onkeydown="if(event.key==='Enter'||event.key===' ')soumettre()"
>Valider</div>

Option 1 : <button> est focusable, répond à Enter et Espace nativement. Option 2 : tabindex="0" rend le div focusable, le listener keydown gère Enter et Espace explicitement.

onglets sans navigation clavier

✗ Non conforme
<div class="tabs">
  <div class="tab" onclick="afficher(0)">Onglet 1</div>
  <div class="tab" onclick="afficher(1)">Onglet 2</div>
</div>

Les onglets ne sont pas focusables. Aucune navigation par flèches. Le pattern APG Tabs exige : Tab pour entrer dans la liste, flèches Gauche/Droite pour changer d'onglet, Tab pour passer au panneau.

onglets avec navigation clavier APG

✓ Conforme
<div role="tablist" aria-label="Sections de contenu">
  <button role="tab" aria-selected="true"
    aria-controls="panneau-1" id="onglet-1"
    tabindex="0">Onglet 1</button>
  <button role="tab" aria-selected="false"
    aria-controls="panneau-2" id="onglet-2"
    tabindex="-1">Onglet 2</button>
</div>
<div role="tabpanel" id="panneau-1"
  aria-labelledby="onglet-1">Contenu 1</div>
<div role="tabpanel" id="panneau-2"
  aria-labelledby="onglet-2" hidden>Contenu 2</div>

<!-- Script : flèches Gauche/Droite changent l'onglet actif
     et mettent à jour tabindex (0 sur actif, -1 sur les autres) -->

Pattern APG Tabs : tabindex="0" sur l'onglet actif, tabindex="-1" sur les autres (roving tabindex). Tab entre dans la liste et en sort. Flèches naviguent entre onglets. aria-selected et aria-controls associent onglets et panneaux.

Référence WCAG : 1.3.1, 2.1.1, 2.4.7

La lettre de l'Atelier A11Y

Ressources pédagogiques, critères RGAA commentés et retours de terrain : une lettre mensuelle pour progresser sur l'accessibilité numérique, sans jargon.

  • Nouveaux articles et ressources pédagogiques
  • Critères RGAA décortiqués avec des exemples concrets
  • Bonnes pratiques et retours d'expérience terrain
S'abonner à la newsletter (s'ouvre dans un nouvel onglet)

Gratuit. Désabonnement possible à tout moment.