Aller au contenu

Le média des artisans du web vendredi 28 août 2026

Design & UX

Focus visible et navigation au clavier : le socle d’accessibilité que l’on oublie

La navigation au clavier ne concerne pas que les lecteurs d'écran : elle décide de l'usage d'un site pour toute personne privée de souris. Ce guide détaille le focus visible, l'ordre de tabulation et les composants qui piègent, avec les règles CSS…

La navigation au clavier ne concerne pas que les lecteurs d’écran. Elle décide de l’usage d’un site pour toute personne privée de souris, à titre temporaire ou permanent, et sert de test de robustesse à l’ensemble de l’interface. Le focus visible et un ordre de tabulation cohérent forment le socle le plus rentable de l’accessibilité, et l’un des plus souvent négligés.

Le clavier, révélateur de la structure

Sur une page correcte, la touche Tab déplace le focus d’un élément interactif au suivant, dans l’ordre où ils apparaissent dans le document. Les éléments natifs (a muni d’un href, button, champs de formulaire) sont focusables sans configuration. Un div auquel on a greffé un gestionnaire de clic ne l’est pas : il reste invisible au clavier tant qu’on ne lui donne pas de rôle et de gestion des touches.

Parcourir un site uniquement au clavier révèle donc en quelques secondes ce qu’aucune capture d’écran ne montre : un menu qu’on ne peut pas atteindre, un bouton fantôme construit à partir d’une image cliquable, un carrousel qui piège le focus. Le clavier ne teste pas seulement l’accessibilité, il teste la solidité du balisage.

:focus-visible plutôt que de supprimer le contour

La faute la plus répandue tient en une déclaration : outline: none, posée pour effacer l’anneau bleu jugé disgracieux au clic. Elle prive du même coup les personnes au clavier du seul repère qui leur indique où elles se trouvent. La solution n’est pas de restaurer l’ancien contour partout, mais de le réserver au bon contexte.

La pseudo-classe :focus-visible laisse le navigateur décider : il affiche l’anneau lorsqu’il estime que le focus vient du clavier, et le masque lors d’un clic à la souris. Le contour n’apparaît donc que là où il sert.

/* Ne jamais retirer le contour sans le remplacer. */
:focus-visible {
  outline: 3px solid #2d6cdf;
  outline-offset: 2px;
  border-radius: 2px;
}

/* Souris : pas d'anneau ; clavier : anneau visible. */
:focus:not(:focus-visible) {
  outline: none;
}

/* Lien d'evitement : masque, revele au focus clavier. */
.skip-link {
  position: absolute;
  left: -9999px;
}
.skip-link:focus {
  left: 1rem;
  top: 1rem;
}

La règle vaut pour tout composant interactif, y compris les éléments personnalisés. Un anneau d’au moins trois pixels, nettement contrasté avec l’arrière-plan et décollé de l’élément par un outline-offset, reste lisible sur la plupart des fonds.

Un site qui ne se parcourt pas entièrement au clavier a un défaut fonctionnel, pas seulement un défaut d’accessibilité.

L’ordre de tabulation suit le DOM

L’ordre dans lequel le focus visite les éléments est celui du code source, pas celui de l’affichage. Un bloc déplacé visuellement en CSS (avec order dans une grille, par exemple) garde sa position d’origine dans la tabulation. Quand l’ordre visuel et l’ordre du DOM divergent, la navigation devient incompréhensible : mieux vaut corriger la structure que compenser au clavier.

Deux outils suffisent dans l’immense majorité des cas. Le lien d’évitement, premier élément focusable de la page, permet de sauter la navigation pour atteindre le contenu. L’attribut tabindex="-1" rend une cible focusable par programme sans l’insérer dans l’ordre de tabulation.

<!-- Premier element focusable de la page -->
<a class="skip-link" href="#contenu">Aller au contenu</a>

<nav>…</nav>

<!-- tabindex="-1" rend la cible focusable par programme,
     sans l'ajouter a l'ordre de tabulation. -->
<main id="contenu" tabindex="-1">
  <h1>Titre de la page</h1>
</main>

Une règle tient l’ensemble : ne jamais utiliser de tabindex positif. Fixer tabindex="1", "2" et ainsi de suite force un ordre artificiel qui se désynchronise du contenu au premier ajout et devient impossible à maintenir. Les seules valeurs saines sont 0 (focusable dans l’ordre naturel) et -1 (focusable par programme uniquement).

Les composants sur mesure, là où ça casse

Menus déroulants, onglets, boîtes de dialogue : dès qu’un composant s’éloigne des éléments natifs, la gestion du clavier devient explicite. Une boîte de dialogue modale, en particulier, doit retenir le focus tant qu’elle est ouverte, faute de quoi la tabulation repart dans la page située derrière elle, hors de vue.

// Piege de focus minimal pour une boite de dialogue.
function piegerFocus(dialogue) {
  const focusables = dialogue.querySelectorAll(
    'a[href], button:not([disabled]), input, select, textarea, [tabindex]:not([tabindex="-1"])'
  );
  const premier = focusables[0];
  const dernier = focusables[focusables.length - 1];

  dialogue.addEventListener('keydown', (e) => {
    if (e.key !== 'Tab') return;
    if (e.shiftKey && document.activeElement === premier) {
      e.preventDefault();
      dernier.focus();
    } else if (!e.shiftKey && document.activeElement === dernier) {
      e.preventDefault();
      premier.focus();
    }
  });
}

Le piège de focus n’est qu’une moitié du contrat. À l’ouverture, le focus doit se porter sur la boîte ou son premier champ ; à la fermeture, il doit revenir sur l’élément qui l’a déclenchée ; la touche Échap doit refermer la boîte. Sans ce cycle complet, la modale reste une trappe pour l’utilisateur au clavier.

Formulaires : libellés associés et focus sur l’erreur

Les formulaires concentrent l’essentiel des interactions au clavier, et une bonne part des défauts. Chaque champ doit être relié à un label explicite, par l’attribut for pointant vers l’id du champ : cliquer sur le libellé donne alors le focus au champ, et les technologies d’assistance annoncent la bonne étiquette. Un placeholder ne remplace pas un libellé, puisqu’il disparaît dès la saisie.

À la validation, le focus doit se porter sur le premier champ en erreur, et le message correspondant être relié au champ par aria-describedby. La personne au clavier est ainsi conduite directement au problème, sans retabuler tout le formulaire pour le localiser.

Quel sélecteur pour quel besoin

SélecteurSe déclenche quandUsage typique
:focusl’élément reçoit le focus, souris ou claviertrop large seul, à éviter pour l’anneau
:focus-visiblele navigateur estime le focus « clavier »l’anneau de focus, cas par défaut
:focus-withinun descendant a le focusmettre en évidence un champ ou un menu parent

Le point de vigilance. outline: none sans remplacement visible est le défaut d’accessibilité le plus courant, et l’un des plus faciles à corriger. Le critère 2.4.7 des WCAG impose un indicateur de focus visible ; la version 2.2 y ajoute des exigences de contraste et de surface minimale pour cet indicateur. Un contrôle rapide : débrancher la souris et parcourir la page entière au clavier.

Ce qu’il faut retenir

  • La navigation au clavier est un test de robustesse de toute l’interface, pas une option pour une minorité.
  • :focus-visible réserve l’anneau de focus au clavier, sans le supprimer pour tout le monde.
  • L’ordre de tabulation suit le DOM ; un lien d’évitement et tabindex limité à 0 et -1 suffisent.
  • Les composants sur mesure exigent une gestion explicite du focus, en particulier les boîtes de dialogue modales.

Sur mes audits, le premier test que je fais est toujours le même : je range la souris et je tabule. En moins d’une minute, la moitié des défauts d’accessibilité d’un site se révèlent, et ce sont rarement les plus coûteux à corriger. Rétablir un focus visible et remettre l’ordre de tabulation d’aplomb tient souvent en quelques lignes de CSS et un lien d’évitement. C’est le meilleur rapport effort / gain que je connaisse sur ce terrain. — Simon Janvier

Pour aller plus loin

Référence : :focus-visible sur MDN Web Docs, et le critère WCAG 2.4.7 « Visibilité du focus ».

À lire aussi sur Mail Studio

Partager LinkedIn Bluesky Hacker News E-mail

À lire aussi