Aller au contenu principal
Accessibilité

Navigation clavier : bonnes pratiques accessibilité web

Guide complet sur la navigation clavier accessible : focus visible, tabulation, raccourcis et RGAA thématique 12. Testez votre site gratuitement.

14 min de lecture

La navigation au clavier est l'un des piliers de l'accessibilité web. Un site qui ne peut pas être utilisé sans souris exclut une part significative de ses utilisateurs : personnes en situation de handicap moteur, utilisateurs de lecteurs d'écran, personnes atteintes de tremblements, et même les power users qui préfèrent le clavier pour sa rapidité. Ce guide couvre l'ensemble des bonnes pratiques, des fondamentaux aux patterns ARIA avancés, avec une attention particulière aux critères de la thématique 12 du RGAA (Navigation).

Pourquoi la navigation clavier est essentielle

Les utilisateurs concernés

La navigation clavier n'est pas un cas marginal. Elle concerne directement :

  • Les personnes en situation de handicap moteur : paralysie, tremblements, amputations, troubles musculo-squelettiques. Certaines utilisent des contacteurs, des systèmes de suivi oculaire ou des claviers adaptés qui simulent tous des interactions clavier.
  • Les utilisateurs de lecteurs d'écran : NVDA, JAWS et VoiceOver reposent entièrement sur la navigation clavier pour parcourir les pages web. L'utilisateur n'interagit jamais avec la souris.
  • Les personnes atteintes de troubles temporaires : bras dans le plâtre, tendinite, fatigue oculaire rendant l'utilisation de la souris difficile.
  • Les power users : développeurs, rédacteurs et professionnels qui privilégient le clavier pour sa rapidité et son efficacité.

En France, on estime que 12 millions de personnes sont en situation de handicap. Parmi elles, les handicaps moteurs et visuels représentent une part importante des utilisateurs qui dépendent du clavier.

Le cadre réglementaire

La navigation clavier est couverte par plusieurs critères du RGAA, principalement dans la thématique 12 (Navigation) mais aussi dans d'autres thématiques :

  • Critère 12.7 : liens d'évitement ou d'accès rapide
  • Critère 12.8 : ordre de tabulation cohérent
  • Critère 12.9 : absence de piège au clavier
  • Critère 7.1 : scripts compatibles avec les technologies d'assistance (incluant le clavier)
  • Critère 7.3 : scripts utilisables au clavier et avec tout dispositif de pointage
  • Critère 10.7 : focus visible

Pour une vue d'ensemble de la conformité RGAA, consultez notre guide sur la définition du RGAA.

Les interactions clavier fondamentales

Tout utilisateur web doit pouvoir naviguer et interagir avec l'ensemble du contenu en utilisant uniquement ces touches.

La touche Tab

Tab est la touche principale de navigation. Elle déplace le focus d'un élément interactif au suivant, dans l'ordre du DOM (l'ordre dans lequel les éléments apparaissent dans le code HTML).

Shift+Tab fait l'inverse : il revient à l'élément interactif précédent.

Les éléments qui reçoivent nativement le focus avec Tab sont :

  • <a href="..."> (liens avec attribut href)
  • <button> (boutons)
  • <input>, <textarea>, <select> (champs de formulaire)
  • <details> / <summary> (éléments de détail)
  • Tout élément avec tabindex="0"

La touche Entrée

Entrée active l'élément actuellement focalisé. Son comportement dépend de l'élément :

  • Sur un lien : suit le lien (navigation)
  • Sur un bouton : déclenche l'action associée
  • Sur un champ de formulaire : soumet le formulaire (si c'est le dernier champ ou un bouton submit)

La touche Espace

Espace a des comportements spécifiques :

  • Sur un bouton : déclenche l'action (identique à Entrée)
  • Sur une case à cocher : coche ou décoche
  • Sur un bouton radio : sélectionne l'option
  • Dans une page : fait défiler vers le bas (comportement natif du navigateur)

Il est important que les composants personnalisés respectent cette distinction entre Entrée et Espace.

Les touches directionnelles

Les flèches haut/bas/gauche/droite servent à la navigation au sein d'un composant :

  • Dans un groupe de boutons radio : changent la sélection
  • Dans un menu : naviguent entre les items
  • Dans un onglet (tabpanel) : changent d'onglet
  • Dans un arbre (tree) : naviguent entre les noeuds

La touche Échap

Échap ferme le composant ou la couche modale en cours :

  • Ferme une modale et retourne le focus sur l'élément déclencheur
  • Ferme un menu déroulant
  • Ferme une infobulle (tooltip)
  • Annule une action en cours

C'est une convention universelle que tous vos composants interactifs doivent respecter.

Gestion du focus

La gestion du focus est le coeur technique de la navigation clavier. Un focus mal géré rend le site inutilisable au clavier, même si chaque composant pris individuellement fonctionne correctement.

Focus visible

Le focus visible est l'indicateur visuel qui montre quel élément est actuellement sélectionné au clavier. C'est l'équivalent du curseur de la souris pour les utilisateurs de clavier.

/* Ne JAMAIS faire ceci sans alternative */
*:focus {
  outline: none;
}

/* Bonne pratique : focus-visible pour cibler uniquement la navigation clavier */
:focus-visible {
  outline: 3px solid #2563eb;
  outline-offset: 2px;
  border-radius: 2px;
}

/* Focus personnalisé par type d'élément */
a:focus-visible {
  outline: 3px solid #2563eb;
  outline-offset: 2px;
}

button:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px #ffffff, 0 0 0 5px #2563eb;
}

input:focus-visible {
  outline: none;
  border-color: #2563eb;
  box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.2);
}

Exigences pour le focus visible :

  • Le focus doit être visible sur tous les éléments interactifs
  • Le contraste de l'indicateur doit être d'au moins 3:1 par rapport à l'arrière-plan adjacent
  • L'indicateur ne doit pas être masqué par d'autres éléments (z-index)
  • Le focus doit être visible quelle que soit la couleur de fond de la page

Utilisez notre calculateur de contraste pour vérifier que votre indicateur de focus est suffisamment visible.

Ordre de tabulation logique

L'ordre dans lequel le focus se déplace avec Tab doit correspondre à l'ordre visuel et logique du contenu. Cet ordre est déterminé par :

  1. L'ordre du DOM (code HTML) — c'est le facteur principal
  2. L'attribut tabindex (modifie l'ordre natif)
  3. Les propriétés CSS order et flex-direction (modifient l'ordre visuel sans changer le DOM)

Le piège du CSS :

/* Danger : l'ordre visuel ne correspond plus au DOM */
.container {
  display: flex;
  flex-direction: row-reverse; /* Inverse visuellement */
}

Si vos éléments sont visuellement dans l'ordre A-B-C mais dans le DOM dans l'ordre C-B-A, le focus suivra C-B-A, ce qui désorientera l'utilisateur. La solution : alignez le DOM avec l'ordre visuel.

L'usage de tabindex :

<!-- tabindex="0" : rend un élément focalisable dans l'ordre normal du DOM -->
<div role="button" tabindex="0">Action personnalisée</div>

<!-- tabindex="-1" : focalisable par script, mais pas par Tab -->
<div id="modal-content" tabindex="-1">Contenu de la modale</div>

<!-- tabindex positif : À ÉVITER ABSOLUMENT -->
<!-- Cela force un ordre de tabulation qui devient ingérable -->
<input tabindex="3"> <!-- NE PAS FAIRE -->
<input tabindex="1"> <!-- NE PAS FAIRE -->
<input tabindex="2"> <!-- NE PAS FAIRE -->

Règle absolue : n'utilisez jamais de tabindex supérieur à 0. Restructurez votre HTML si l'ordre de tabulation n'est pas correct.

Liens d'évitement (skip links)

Les liens d'évitement sont le premier élément interactif de la page. Ils permettent aux utilisateurs de clavier de sauter directement au contenu principal sans parcourir toute la navigation.

<body>
  <a href="#contenu" class="skip-link">Aller au contenu principal</a>
  <a href="#navigation" class="skip-link">Aller à la navigation</a>
  <a href="#recherche" class="skip-link">Aller à la recherche</a>

  <header>
    <nav id="navigation" aria-label="Navigation principale">
      <!-- Menu principal -->
    </nav>
    <form id="recherche" role="search" aria-label="Recherche sur le site">
      <!-- Barre de recherche -->
    </form>
  </header>

  <main id="contenu" tabindex="-1">
    <!-- Contenu principal -->
  </main>
</body>
.skip-link {
  position: absolute;
  top: -100%;
  left: 16px;
  padding: 12px 24px;
  background-color: #1a1a2e;
  color: #ffffff;
  font-weight: 600;
  z-index: 9999;
  border-radius: 0 0 8px 8px;
  text-decoration: none;
}

.skip-link:focus {
  top: 0;
}

Le lien vers #contenu est obligatoire selon le critère 12.7 du RGAA. Les liens vers la navigation et la recherche sont recommandés mais non obligatoires. Pour générer du code prêt à l'emploi, utilisez notre générateur de liens d'évitement.

Gestion du focus dans les composants dynamiques

Les composants interactifs modernes (modales, menus, onglets, carrousels) nécessitent une gestion de focus spécifique pour être utilisables au clavier.

Les modales (dialogues)

La modale est le composant qui demande la gestion de focus la plus rigoureuse.

<button id="open-modal" aria-haspopup="dialog">Ouvrir les paramètres</button>

<dialog id="settings-dialog" aria-labelledby="dialog-title">
  <h2 id="dialog-title">Paramètres</h2>
  <form method="dialog">
    <label for="theme">Thème</label>
    <select id="theme">
      <option>Clair</option>
      <option>Sombre</option>
    </select>
    <button type="submit">Enregistrer</button>
    <button type="button" id="close-dialog">Annuler</button>
  </form>
</dialog>
const dialog = document.getElementById('settings-dialog');
const openButton = document.getElementById('open-modal');
const closeButton = document.getElementById('close-dialog');

// Ouvrir : le focus va dans la modale
openButton.addEventListener('click', () => {
  dialog.showModal(); // Le navigateur gère le focus trap nativement
});

// Fermer avec le bouton Annuler
closeButton.addEventListener('click', () => {
  dialog.close();
  openButton.focus(); // Retour du focus sur le déclencheur
});

// Fermer avec Échap (natif avec <dialog>, mais ajoutez le retour du focus)
dialog.addEventListener('close', () => {
  openButton.focus();
});

L'élément HTML <dialog> avec showModal() est la meilleure approche en 2026 : le navigateur gère nativement le piège de focus (focus trap), l'overlay et la fermeture avec Échap.

Règles de la modale :

  1. Le focus entre dans la modale à l'ouverture (premier élément interactif ou la modale elle-même)
  2. Le focus reste dans la modale (piège de focus : Tab boucle dans la modale)
  3. Échap ferme la modale
  4. Le focus retourne à l'élément qui a ouvert la modale à la fermeture

Les menus déroulants

Pour les menus de navigation, le pattern recommandé est le disclosure pattern (afficher/masquer) plutôt que le pattern ARIA menu complet.

<nav aria-label="Navigation principale">
  <ul>
    <li>
      <button aria-expanded="false" aria-controls="submenu-services">
        Services
      </button>
      <ul id="submenu-services" hidden>
        <li><a href="/audit">Audit RGAA</a></li>
        <li><a href="/formation">Formation</a></li>
        <li><a href="/conseil">Conseil</a></li>
      </ul>
    </li>
    <li><a href="/blog">Blog</a></li>
    <li><a href="/contact">Contact</a></li>
  </ul>
</nav>
const menuButton = document.querySelector('[aria-controls="submenu-services"]');
const submenu = document.getElementById('submenu-services');

menuButton.addEventListener('click', () => {
  const isExpanded = menuButton.getAttribute('aria-expanded') === 'true';
  menuButton.setAttribute('aria-expanded', !isExpanded);
  submenu.hidden = isExpanded;
});

// Fermer avec Échap
submenu.addEventListener('keydown', (e) => {
  if (e.key === 'Escape') {
    menuButton.setAttribute('aria-expanded', 'false');
    submenu.hidden = true;
    menuButton.focus();
  }
});

Les onglets (tabs)

Les onglets suivent le pattern ARIA tablist/tab/tabpanel avec navigation par flèches.

<div role="tablist" aria-label="Sections du contenu">
  <button role="tab" id="tab-1" aria-selected="true" aria-controls="panel-1">
    Présentation
  </button>
  <button role="tab" id="tab-2" aria-selected="false" aria-controls="panel-2"
          tabindex="-1">
    Tarifs
  </button>
  <button role="tab" id="tab-3" aria-selected="false" aria-controls="panel-3"
          tabindex="-1">
    FAQ
  </button>
</div>

<div role="tabpanel" id="panel-1" aria-labelledby="tab-1">
  <!-- Contenu Présentation -->
</div>
<div role="tabpanel" id="panel-2" aria-labelledby="tab-2" hidden>
  <!-- Contenu Tarifs -->
</div>
<div role="tabpanel" id="panel-3" aria-labelledby="tab-3" hidden>
  <!-- Contenu FAQ -->
</div>

Comportement clavier attendu :

  • Tab : amène le focus dans le tablist (sur l'onglet actif), puis le Tab suivant sort du tablist vers le contenu du panel
  • Flèche gauche/droite : navigue entre les onglets
  • Home : va au premier onglet
  • End : va au dernier onglet

C'est le pattern du roving tabindex : seul l'onglet actif a tabindex="0", les autres ont tabindex="-1". Les flèches déplacent le focus et mettent à jour le tabindex.

Patterns ARIA avancés

Roving tabindex

Le roving tabindex est un pattern où un seul élément d'un groupe est focalisable via Tab à tout moment. Les flèches directionnelles permettent de naviguer au sein du groupe.

function handleArrowNavigation(items, currentIndex, event) {
  let newIndex = currentIndex;

  switch (event.key) {
    case 'ArrowRight':
    case 'ArrowDown':
      newIndex = (currentIndex + 1) % items.length;
      break;
    case 'ArrowLeft':
    case 'ArrowUp':
      newIndex = (currentIndex - 1 + items.length) % items.length;
      break;
    case 'Home':
      newIndex = 0;
      break;
    case 'End':
      newIndex = items.length - 1;
      break;
    default:
      return; // Ne pas empêcher le comportement par défaut
  }

  event.preventDefault();

  // Mettre à jour le tabindex
  items[currentIndex].setAttribute('tabindex', '-1');
  items[newIndex].setAttribute('tabindex', '0');
  items[newIndex].focus();
}

Ce pattern est utilisé pour les onglets, les barres d'outils, les groupes de boutons radio et les menus.

aria-activedescendant

Alternative au roving tabindex, aria-activedescendant permet de gérer le focus virtuel sans déplacer le focus réel. Le conteneur garde le focus et annonce l'élément actif via l'attribut.

<div role="listbox" tabindex="0" aria-activedescendant="option-2"
     aria-label="Choisir un pays">
  <div role="option" id="option-1">France</div>
  <div role="option" id="option-2" aria-selected="true">Belgique</div>
  <div role="option" id="option-3">Suisse</div>
</div>

Ce pattern est particulièrement utile pour les combobox (champ de recherche avec suggestions) et les listbox complexes.

Les pièges courants à éviter

Piège 1 : éléments interactifs non focalisables

<!-- Mauvais : div non focalisable avec événement de clic -->
<div class="card" onclick="openDetail()">Voir le détail</div>

<!-- Bon : bouton natif -->
<button class="card" onclick="openDetail()">Voir le détail</button>

<!-- Acceptable : div avec rôle et tabindex -->
<div class="card" role="button" tabindex="0"
     onclick="openDetail()"
     onkeydown="if(event.key==='Enter'||event.key===' ')openDetail()">
  Voir le détail
</div>

Préférez toujours les éléments natifs (<button>, <a>, <input>) qui gèrent nativement le clavier. Un <div> avec role="button" nécessite de recréer manuellement tout le comportement clavier. Consultez notre outil bouton vs lien pour choisir le bon élément.

Piège 2 : contenu affiché au survol seulement

/* Mauvais : visible uniquement au hover souris */
.tooltip {
  display: none;
}
.trigger:hover .tooltip {
  display: block;
}

/* Bon : visible au hover ET au focus */
.tooltip {
  display: none;
}
.trigger:hover .tooltip,
.trigger:focus-within .tooltip {
  display: block;
}

Piège 3 : gestionnaires d'événements souris sans équivalent clavier

// Mauvais : seulement la souris
element.addEventListener('mousedown', handler);

// Bon : souris ET clavier
element.addEventListener('click', handler); // click est déclenché par Entrée aussi
element.addEventListener('keydown', (e) => {
  if (e.key === 'Enter' || e.key === ' ') {
    e.preventDefault();
    handler(e);
  }
});

Piège 4 : focus perdu après manipulation du DOM

Lorsqu'un élément focalisé est supprimé du DOM (fermeture d'un composant, pagination, mise à jour AJAX), le focus est perdu et retourne au début de la page. C'est extrêmement désorientant.

// Mauvais : l'élément focalisé est supprimé sans gestion du focus
deleteButton.addEventListener('click', () => {
  listItem.remove(); // Le focus est perdu
});

// Bon : le focus est déplacé avant la suppression
deleteButton.addEventListener('click', () => {
  const nextItem = listItem.nextElementSibling || listItem.previousElementSibling;
  listItem.remove();
  if (nextItem) {
    nextItem.querySelector('button')?.focus();
  }
});

Piège 5 : raccourcis clavier qui entrent en conflit

Si vous implémentez des raccourcis clavier personnalisés, assurez-vous qu'ils n'entrent pas en conflit avec les raccourcis du navigateur ou des technologies d'assistance.

Le RGAA (via WCAG 2.1) impose que les raccourcis clavier à une seule touche (lettre, chiffre, ponctuation) puissent être désactivés ou remappés par l'utilisateur (critère 12.14 du RGAA 4). Utilisez des combinaisons avec Ctrl, Alt ou Meta pour vos raccourcis.

Méthodologie de test

Test manuel de base

Voici une procédure de test en 10 étapes que vous pouvez réaliser vous-même :

  1. Débranchez votre souris (ou ne l'utilisez pas) pendant tout le test
  2. Appuyez sur Tab : le premier élément focalisé est-il le lien d'évitement ?
  3. Activez le lien d'évitement : le focus va-t-il au contenu principal ?
  4. Parcourez la page entière avec Tab : chaque élément interactif reçoit-il le focus ?
  5. Le focus est-il toujours visible ? Le suivez-vous facilement ?
  6. L'ordre de tabulation correspond-il à l'ordre visuel logique ?
  7. Testez chaque formulaire : les champs sont-ils étiquetés ? Les messages d'erreur sont-ils accessibles ?
  8. Testez chaque composant interactif (menu, modale, onglets) : fonctionne-t-il au clavier ?
  9. Pouvez-vous toujours sortir d'un composant avec Tab ou Échap ? (Vérifiez l'absence de pièges clavier)
  10. Après chaque interaction (ouverture/fermeture de modale, suppression), le focus est-il géré correctement ?

Test avec un lecteur d'écran

Pour un test plus complet, activez un lecteur d'écran :

  • VoiceOver (macOS) : Cmd+F5 pour activer, VO+flèches pour naviguer
  • NVDA (Windows) : téléchargement gratuit, Insert+flèches pour naviguer
  • Orca (Linux) : Super+Alt+S pour activer

Naviguez sur votre site et vérifiez que :

  • Le contenu est annoncé dans un ordre logique
  • Les éléments interactifs sont correctement identifiés (bouton, lien, case à cocher...)
  • Les états sont annoncés (étendu/réduit, coché/décoché, sélectionné)
  • Les régions et landmarks sont présentes (navigation, contenu principal, pied de page)

Outils d'aide au test

Combinez le test manuel avec des outils automatisés pour une couverture optimale :

Récapitulatif des bonnes pratiques

Pour garantir une navigation clavier complète et conforme, retenez ces principes essentiels :

  • Utilisez les éléments HTML natifs chaque fois que possible (button, a, input, dialog)
  • Ne supprimez jamais l'outline sans fournir un indicateur de focus alternatif visible
  • N'utilisez jamais tabindex > 0 — restructurez votre HTML à la place
  • Gérez le focus lors de chaque changement dynamique (ouverture/fermeture, ajout/suppression)
  • Respectez les conventions clavier : Tab pour naviguer, Entrée/Espace pour activer, Échap pour fermer, flèches pour naviguer dans un composant
  • Testez régulièrement sans souris, avec un lecteur d'écran activé

Ces pratiques ne sont pas seulement une obligation réglementaire — elles améliorent l'expérience de tous vos utilisateurs. Un site navigable au clavier est un site mieux structuré, plus robuste et plus performant. Pour aller plus loin, identifiez les erreurs d'accessibilité les plus courantes sur votre site et consultez notre guide sur l'audit RGAA pour planifier votre démarche de conformité.

claviernavigationaccessibilitéfocusRGAA

Questions fréquentes

Pourquoi la navigation clavier est-elle si importante ?

La navigation clavier est essentielle pour les personnes utilisant des lecteurs d'écran, des contacteurs, ou ne pouvant pas utiliser une souris. C'est aussi un critère obligatoire du RGAA (thématique 7 et 12). Un site non navigable au clavier est inaccessible à une part significative des utilisateurs.

Comment tester la navigation clavier de mon site ?

Débranchez votre souris et naviguez avec Tab (avancer), Shift+Tab (reculer), Entrée (activer), Espace (cocher/ouvrir), Échap (fermer). Vérifiez que le focus est toujours visible, qu'il n'y a pas de piège au clavier, et que tous les éléments interactifs sont atteignables.

Qu'est-ce qu'un piège au clavier ?

Un piège au clavier se produit quand l'utilisateur ne peut plus quitter un élément avec Tab ou Échap. Cela arrive souvent dans les modales, lecteurs vidéo ou menus déroulants mal implémentés. C'est un critère RGAA bloquant.

Testez l'accessibilité de votre site

Analysez votre site en quelques secondes avec notre scanner RGAA automatisé.

Lancer un scan gratuit