Tabindex
L'attribut HTML tabindex contrôle si un élément peut recevoir le focus clavier et dans quel ordre. Trois valeurs existent : 0 pour inclure un élément dans l'ordre naturel de tabulation, -1 pour le rendre focusable uniquement via JavaScript, et les valeurs positives, que vous ne devriez jamais utiliser.
Un <div> cliquable ne reçoit pas le focus quand vous appuyez sur Tab. Pour le navigateur, ce n'est qu'un conteneur. L'attribut tabindex change ça : il indique au navigateur quels éléments doivent participer à la navigation clavier, et lesquels doivent en être exclus.
#Trois valeurs, trois comportements
tabindex accepte un entier. Seules deux valeurs méritent votre attention.
tabindex="0" insère l'élément dans l'ordre de tabulation naturel, à sa position dans le DOM. Un <div> avec tabindex="0" sera atteint par Tab au même titre qu'un bouton ou un lien :
<div role="button" tabindex="0">Valider</div>tabindex="-1" retire l'élément de l'ordre de tabulation, mais le rend focusable via JavaScript avec element.focus(). C'est la valeur utilisée pour les cibles de liens d'évitement, les modales, ou les messages d'erreur :
<main id="contenu" tabindex="-1">…</main>
<script>
document.querySelector('#contenu').focus();
</script>Les valeurs positives (tabindex="1", "5", "32") créent un ordre parallèle. L'élément reçoit le focus avant tous les éléments en tabindex="0", quelle que soit sa position dans le code. Sur une page de 50 éléments interactifs, un seul tabindex="1" suffit à rendre le parcours imprévisible. Le W3C le déconseille formellement.
#L'erreur qui passe inaperçue
Ajouter tabindex="0" à un élément non interactif, comme un paragraphe, une image ou un titre. L'élément reçoit le focus, mais rien ne se passe quand l'utilisateur appuie sur Entrée. Chaque tabindex inutile ajoute un arrêt supplémentaire dans le parcours clavier. Pour quelqu'un qui navigue un formulaire de 20 champs, ces arrêts fantômes deviennent vite pénibles.
Autre piège : poser tabindex="0" sur un composant personnalisé et considérer le travail terminé. Le composant est focusable, mais sans rôle ARIA ni gestion des touches Entrée et Espace, il reste muet pour les lecteurs d'écran. Un <button> natif gère tout ça pour vous.
Utilisez-le.
#En résumé
tabindex="0" pour rendre un élément focusable. tabindex="-1" pour le focus programmatique. Les valeurs positives, jamais. Et avant d'ajouter un tabindex, posez-vous la question : un élément HTML natif ne ferait-il pas le travail sans configuration ?