Le brouillon de travail CSS Selectors Level 4 du W3C décrit ainsi l’intention du sélecteur :focus-visible : permettre aux auteurs de styles de n’appliquer un indicateur de focus visible que lorsque l’agent utilisateur détermine, selon des heuristiques qui lui sont propres, que cet indicateur est utile à l’utilisateur. Autrement dit, laisser le navigateur décider si le focus vient d’une interaction clavier ou d’un clic de souris, plutôt que de le déduire soi-même en JavaScript.
Cette promesse répond à une frustration ancienne côté intégration : le sélecteur :focus seul s’applique à chaque prise de focus, y compris après un clic de souris sur un bouton, ce qui produit un contour bleu épais jugé disgracieux par beaucoup d’équipes de design, qui finissent par le supprimer entièrement avec outline: none, sans jamais le réintroduire pour la navigation clavier.
La mécanique interne du sélecteur
Le principe retenu par la spécification n’est pas un simple test « le focus vient-il du clavier ? ». Le navigateur applique un ensemble d’heuristiques qui tiennent compte du type d’élément, du mode d’interaction précédent et du contexte de la page. Un champ de texte, par exemple, reçoit l’indicateur visuel même après un clic de souris, parce qu’un curseur de saisie doit toujours rester repérable. Un bouton, en revanche, ne le reçoit qu’après une activation au clavier, typiquement via la touche Tab.
Cette distinction fine est précisément ce qu’un script JavaScript maison a du mal à reproduire fidèlement. La plupart des implémentations artisanales se contentent d’écouter les événements keydown et mousedown pour poser une classe sur le <body>, une approximation qui fonctionne dans les cas simples mais qui rate les subtilités par type d’élément.

L’état du support au moment d’écrire ces lignes
À ce jour, aucun navigateur ne livre encore d’implémentation conforme au dernier texte du brouillon sous le nom exact :focus-visible. Firefox propose depuis longtemps un sélecteur non standard équivalent, :-moz-focusring, qui répond à la même intention mais avec une syntaxe propriétaire. Chromium prépare une implémentation, suivie sur son gestionnaire de tickets public, sans date de livraison stable annoncée pour l’instant. Utiliser :focus-visible directement dans une feuille de style de production reste donc prématuré sans filet de sécurité.
Le groupe de travail communautaire WICG maintient un polyfill JavaScript qui reproduit ces heuristiques et ajoute une classe .focus-visible sur les éléments concernés, avec une feuille de style correspondante à écrire soi-même. C’est aujourd’hui la seule façon fiable d’obtenir ce comportement de manière cohérente sur l’ensemble des navigateurs ciblés par un projet WordPress grand public.
Mettre le polyfill en place
<!-- Chargement du script du groupe communautaire WICG -->
<script src="/wp-content/themes/mon-theme/js/focus-visible.min.js" defer></script>
/* La classe posée par le polyfill remplace la pseudo-classe absente */
.bouton:focus:not(.focus-visible) {
outline: none;
}
.bouton.focus-visible {
outline: 3px solid #1a5fb4;
outline-offset: 2px;
}
Cette double règle reproduit l’esprit du sélecteur natif : le contour disparaît pour une activation à la souris, il reste pour une navigation au clavier, sans jamais supprimer totalement l’indicateur de focus, ce qui serait un manquement direct au critère 2.4.7 des Web Content Accessibility Guidelines, consacré à la visibilité du focus.
Un piège fréquent à éviter dès maintenant
Beaucoup de resets CSS suppriment outline sans jamais réintroduire d’alternative, dans l’idée de « nettoyer » l’apparence par défaut du navigateur. Ce choix, très répandu dans les thèmes premium, retire un repère indispensable à la navigation clavier sans rien proposer en remplacement. Ce sujet mériterait un article à lui seul ; il ne sera pas développé davantage ici.
- Ne jamais poser
outline: nonesans règle de remplacement immédiatement associée - Tester la navigation au clavier après tout reset CSS global
- Préférer le polyfill WICG à une détection maison tant que le support natif reste partiel
Ce qu’il faut retenir de ce sélecteur en devenir
Le principe de :focus-visible répond à un vrai besoin de conception : distinguer l’interaction clavier de l’interaction souris sans jugement binaire naïf. Sa mécanique, fondée sur des heuristiques par type d’élément plutôt que sur un simple test d’événement, dépasse ce qu’un script maison reproduit d’habitude. Le brouillon n’est pas figé et son support navigateur reste incomplet à ce jour : le polyfill communautaire constitue, pour l’instant, l’option la plus robuste pour un site en production, en attendant une adoption plus large.
Un repère de vigilance à garder en tête pour la suite : dès qu’un support natif deviendra fiable sur les navigateurs ciblés, il faudra prévoir de retirer le polyfill devenu redondant, pas seulement d’ajouter le nouveau sélecteur par-dessus.