Popover natif et focusgroup : sortir d'ARIA sans casser le RGAA
En Bref : L'essentiel à retenir
- L'attribut popover (avec popovertarget) ferme le besoin de JavaScript pour ouvrir/fermer un panneau : fermeture à Échap, au clic extérieur, et rendu hors z-index via le top layer.
- Le popover natif n'effectue aucune gestion du focus : ordre du DOM, entrée dans le panneau, retour au déclencheur restent entièrement à la charge du développeur (critères RGAA 7.1 et 7.3).
- L'attribut focusgroup (Chrome 150) automatise la navigation aux flèches dans un groupe de contrôles, mais son support est mono-navigateur et son rendu chez les lecteurs d'écran est encore incohérent : pas de production sans repli JavaScript.
- Une primitive native ne dispense jamais du test manuel : le RGAA reste ~60 % manuel, et la compatibilité lecteur d'écran d'un composant popover ou focusgroup doit être vérifiée à la main, pas supposée.
Un accordéon en ARIA et JavaScript, cela s'écrit toujours à peu près pareil : un bouton avec aria-expanded, un panneau avec hidden, un gestionnaire de clic qui bascule les deux, un keydown pour Échap, et souvent un z-index qu'on ajuste à la main quand le panneau se retrouve sous un autre élément. Deux nouvelles primitives HTML proposent de faire disparaître une partie de ce code : l'attribut popover (avec popovertarget) pour les panneaux qui s'ouvrent et se ferment, et l'attribut focusgroup pour la navigation aux flèches dans un groupe de contrôles.
La promesse est réelle : moins de JavaScript, moins de bugs de synchronisation d'état. Mais « moins de code » ne veut pas dire « accessible par défaut ». Ces primitives comblent certains trous qu'ARIA+JS demandait de coder soi-même, et en laissent d'autres grands ouverts, en particulier la gestion du focus. Cet article fait l'inventaire précis de ce que le natif fait gratuitement, de ce qui reste à votre charge, et à partir de quand focusgroup est encore trop jeune pour la production.
Ce que l'attribut popover fait gratuitement
Le développeur et consultant en accessibilité Adrian Roselli a documenté une réécriture d'un ancien pattern de navigation (initialement construit en 2019 avec des widgets de divulgation ARIA et <details>) en remplaçant la mécanique d'ouverture par des popovers HTML natifs (Link + Popover Navigation). La structure minimale tient en trois éléments : un lien de navigation, un bouton déclencheur, et un panneau.
<li>
<a href="/produits" aria-current="page">Produits</a>
<button type="button" popovertarget="sous-menu-produits">
Sous-menu
</button>
<ul id="sous-menu-produits" popover>
<li><a href="/produits/logiciels">Logiciels</a></li>
<li><a href="/produits/services">Services</a></li>
</ul>
</li>
Trois comportements sont pris en charge par le navigateur sans une ligne de script :
- Ouverture et fermeture : le clic sur le bouton bascule la visibilité du panneau. Aucun gestionnaire de clic à écrire.
- Fermeture à Échap et au clic extérieur : ce comportement est natif au popover, là où ARIA+JS demandait un
keydownsurdocumentet un test de clic hors du composant. - Rendu sur le top layer : le panneau s'affiche dans une couche d'empilement dédiée du navigateur, au-dessus du reste de la page, sans conflit de
z-indexavec un en-tête sticky ou une barre latérale.
Le couple popovertarget/popover expose aussi l'état d'ouverture aux technologies d'assistance : il n'est pas nécessaire de gérer aria-expanded à la main sur le bouton, l'association déclencheur/panneau le fait automatiquement. C'est exactement le type de synchronisation d'état qu'on oubliait de mettre à jour dans un coin du code, six mois après la mise en production.
Comparé à un menu déroulant ou une méga-navigation entièrement câblés en ARIA et JavaScript (le pattern que nous détaillons dans notre guide des méga-menus accessibles), c'est un gain net : moins de surface de bug, moins de JavaScript à maintenir, un comportement d'empilement visuel qui ne dépend plus de la feuille de style du reste du site.
Ce que popover ne fait jamais : le focus
Voici le point que beaucoup d'équipes ratent en découvrant popover : il ne gère aucun aspect du focus. Roselli est explicite sur ce point : « The popover feature does not automatically do any focus management », littéralement « la fonctionnalité popover ne fait automatiquement aucune gestion du focus ». Trois conséquences concrètes.
L'entrée dans le panneau n'est pas automatique
Quand le popover s'ouvre, le focus clavier reste où il était (en général sur le bouton déclencheur). Pour un panneau de navigation simple, contenant uniquement des liens, cela peut être acceptable : l'utilisateur au clavier appuie sur Tab et atteint naturellement le premier lien du panneau. Mais pour un panneau qui doit se comporter comme une boîte de dialogue ou une liste de sélection, c'est à vous de déplacer le focus vous-même vers le premier élément pertinent à l'ouverture.
L'ordre du DOM doit suivre l'ordre visuel
Le panneau popover doit être placé immédiatement après son déclencheur dans le DOM. Si le panneau est positionné ailleurs dans l'arborescence (par exemple regroupé avec d'autres popovers en fin de document, une pratique courante pour éviter les problèmes d'overflow: hidden d'un parent), l'ordre de lecture et l'ordre de tabulation ne correspondent plus à l'ordre visuel. Un lecteur d'écran en navigation séquentielle annoncera le contenu dans le désordre, et un utilisateur au clavier verra le focus sauter d'un bout à l'autre de la page.
La fermeture sur perte de focus reste à coder
Le popover se ferme à Échap et au clic extérieur, nativement. Mais la fermeture quand le focus sort du panneau par tabulation (focusout), un comportement attendu pour de nombreux menus, n'est pas automatique. Roselli est direct : « You'll have to write your own », vous devrez l'écrire vous-même. C'est un gestionnaire d'événement en plus, exactement le genre de code que popover était censé vous épargner.
Ce que cela veut dire pour le RGAA
Le glossaire du RGAA 4.1.2 définit un script comme du « code généralement écrit sous forme d'une liste de commandes [...] les commandes d'un langage de script côté client peuvent être embarquées ou contenues dans un fichier externe ». Au sens strict, un attribut HTML déclaratif comme popover n'est pas un script : c'est le moteur du navigateur qui exécute le comportement, pas votre code.
Cette nuance ne change rien à l'obligation de résultat. Un composant d'interface qui s'ouvre, se ferme, et change d'état reste un composant d'interface, que son comportement soit produit par 40 lignes de JavaScript ou par un attribut HTML. Un auditeur RGAA testera le résultat produit, exactement comme il le ferait pour un composant fait main, via les deux critères qui couvrent l'interactivité dynamique.
Critère 7.1 (« Chaque script est-il, si nécessaire, compatible avec les technologies d'assistance ? ») demande, entre autres, que le nom, le rôle, la valeur et les changements d'état d'un composant d'interface soient accessibles via une API d'accessibilité (test 7.1.1). Popover coche une bonne partie de cette case gratuitement : l'état d'ouverture est exposé sans configuration ARIA manuelle. Ce que 7.1 ne garantit pas pour autant, c'est que le contenu du panneau soit restitué dans le bon ordre, ni que le nom du panneau (s'il en a besoin d'un) soit correctement porté.
Critère 7.3 (« Chaque script est-il contrôlable par le clavier et par tout dispositif de pointage ? ») est là où le trou de focus devient un problème de conformité concret. Le test 7.3.2 est sans ambiguïté : « Un script ne doit pas supprimer le focus d'un élément qui le reçoit ». Si votre panneau se ferme (au clic sur un lien, à Échap, ou en perdant le focus) et que l'élément qui avait le focus disparaît du DOM ou devient masqué sans qu'un autre élément visible ne récupère le focus, celui-ci retombe silencieusement sur <body>. L'utilisateur au clavier perd alors tout repère de sa position dans la page. C'est un scénario que le natif ne prévient absolument pas : à vous de renvoyer explicitement le focus vers le déclencheur (ou un autre point logique) à la fermeture.
Notre guide du critère 7.1 et notre guide du critère 7.3 détaillent les tests un par un si vous voulez vérifier votre implémentation point par point.
focusgroup : la promesse de la navigation aux flèches sans JavaScript
Le deuxième chantier de Roselli porte sur focusgroup, une proposition Open-UI implémentée dans Chrome 150 (Focusgroup Tests). L'idée : automatiser la navigation aux flèches directionnelles dans les groupes de contrôles composites qui l'exigent par construction ARIA (listbox, menu, menubar, radiogroup, tablist, toolbar), sans écrire le moindre gestionnaire de keydown.
<ul role="tablist" focusgroup>
<li role="tab" tabindex="0">Onglet 1</li>
<li role="tab" tabindex="-1">Onglet 2</li>
<li role="tab" tabindex="-1">Onglet 3</li>
</ul>
Aujourd'hui, un pattern d'onglets en ARIA demande de gérer soi-même le roving tabindex (un seul élément du groupe est focusable à la fois, les flèches déplacent ce focus) et l'écoute des touches directionnelles. focusgroup propose de déléguer cette mécanique au navigateur, avec une direction et un bouclage adaptés au rôle du groupe.
Pourquoi ce n'est pas encore pour la production
Trois réserves sérieuses ressortent des tests de Roselli, et elles justifient de traiter focusgroup comme expérimental.
Le support est mono-navigateur. L'article est explicite : « You'll need Chrome 150 to test these today », vous aurez besoin de Chrome 150 pour tester cela aujourd'hui. Edge explore des travaux connexes sur la gestion du focus, mais aucune implémentation croisée n'est disponible au moment de la rédaction. Sans repli JavaScript, une interface qui compte sur focusgroup seul est inutilisable au clavier dans tout autre navigateur.
Le rôle ne peut pas être neutralisé. Roselli documente un piège précis : ajouter role="presentation" à un nœud portant focusgroup n'a aucun effet, le rôle issu du focusgroup reste exposé. Pire, en combinant focusgroup="menubar" avec des rôles ARIA existants, les <li> enfants perdent leur rôle et les <button> qu'ils contiennent se voient réattribuer le rôle menuitem par remontée (« role-up »). Une structure mal anticipée peut donc se retrouver avec des rôles qui ne correspondent plus à l'intention de balisage d'origine.
Le rendu chez les lecteurs d'écran est incohérent. En mode curseur virtuel, NVDA et JAWS empêchent la navigation lettre par lettre à l'intérieur d'un bouton sans forcer la sortie du mode formulaire, un comportement que Roselli qualifie lui-même de contre-intuitif (« feels buggy »). C'est exactement le type de divergence entre navigateurs, lecteurs d'écran et modes de navigation que seul un test manuel révèle : aucun scanner automatisé, le nôtre y compris, ne peut détecter ce genre d'incohérence de restitution.
Note
focusgroup est une proposition récente au support limité à un seul moteur de rendu. Traitez-la comme une piste à surveiller, pas comme un remplacement immédiat de vos widgets ARIA+JS en production. Si vous l'expérimentez, gardez impérativement un repli JavaScript fonctionnel pour les navigateurs qui ne l'implémentent pas encore.
Grille de décision : natif ou ARIA+JavaScript ?
Face à un nouveau composant à construire, voici comment trancher entre primitive native et pattern ARIA+JavaScript classique.
| Situation | Recommandation | Pourquoi |
|---|---|---|
| Panneau simple (sous-menu de liens, info-bulle de contenu) sans navigation aux flèches | popover natif, avec gestion manuelle du focus à la fermeture | Le gain (Échap, clic extérieur, top layer) dépasse largement le coût (un gestionnaire focusout et un retour de focus explicite) |
| Widget composite critique (listbox, tablist, menu à flèches) en production | ARIA + JavaScript (roving tabindex classique) | focusgroup n'est disponible que sur Chrome 150 ; un widget de production doit fonctionner partout |
| Prototype interne ou démonstrateur testé uniquement sur Chrome récent | focusgroup en expérimentation, avec vigilance sur les rôles | Permet d'évaluer l'ergonomie de code sans risque utilisateur, à condition de documenter la limite de support |
| Support de navigateurs anciens ou parc hétérogène imposé | ARIA + JavaScript avec polyfill si besoin | Le popover et focusgroup n'ont pas de repli automatique : sans polyfill, l'absence de support rend le composant inopérant |
Dans tous les cas, la bascule vers le natif ne dispense jamais du test manuel avec un lecteur d'écran réel, exactement comme le guide sur la navigation clavier le rappelle pour les patterns ARIA classiques : un score automatisé n'atteste jamais, à lui seul, qu'un composant est utilisable au clavier ou correctement restitué.
Checklist avant de basculer un composant vers popover
Si vous remplacez un pattern ARIA+JS existant par popover, vérifiez ces cinq points avant de considérer le chantier terminé :
- Le panneau
popoverest-il placé immédiatement après son déclencheur dans le DOM, et pas regroupé ailleurs dans la page ? - Le focus est-il explicitement déplacé vers un élément pertinent à l'ouverture si le panneau doit se comporter comme une boîte de dialogue ou une liste de sélection ?
- Le focus revient-il de façon prévisible sur le déclencheur (ou un autre point logique) à la fermeture, plutôt que de retomber sur
<body>? - La fermeture sur perte de focus (
focusout) a-t-elle été implémentée si l'ergonomie du composant l'exige ? - Le composant a-t-il été testé au clavier seul et avec au moins un lecteur d'écran réel (NVDA, JAWS ou VoiceOver), pas seulement audité par un outil automatisé ?
Ce dernier point n'est pas optionnel. Le RGAA reste construit aux deux tiers sur du test manuel : aucun scanner, y compris le nôtre, ne peut certifier qu'un couple bouton/popover se comporte correctement pour un utilisateur de lecteur d'écran. Un audit automatique gratuit repère les manques de structure évidents (rôle manquant, attribut mal posé), mais la validation du focus et de l'ordre de lecture reste, à ce jour, un travail humain.
Conclusion
popover et focusgroup déplacent une partie réelle et non négligeable du travail d'accessibilité vers le navigateur : état d'ouverture exposé sans ARIA manuel, fermeture à Échap et au clic extérieur gratuite, empilement visuel réglé par le top layer, et à terme une promesse de navigation aux flèches sans le moindre keydown. Mais aucune des deux primitives ne gère le focus à votre place, et focusgroup reste, au moment de la rédaction, une implémentation mono-navigateur dont le rendu chez les lecteurs d'écran présente des incohérences documentées.
La règle pratique à retenir : basculez vers le natif pour les panneaux simples dès aujourd'hui, en codant vous-même le retour de focus et la fermeture sur perte de focus ; gardez ARIA+JavaScript pour tout widget composite critique en production ; réservez focusgroup à l'expérimentation, avec repli JavaScript, jusqu'à ce que son support s'élargisse et que sa restitution chez les lecteurs d'écran se stabilise. Et dans tous les cas, testez au clavier et avec un vrai lecteur d'écran avant de livrer : c'est la seule vérification que ni popover ni focusgroup ne peuvent remplacer.
Questions fréquentes
L'attribut popover remplace-t-il complètement ARIA et JavaScript ?
Non. Il remplace la mécanique d'ouverture/fermeture (état, Échap, clic extérieur, empilement visuel). Il ne remplace pas la gestion du focus, l'ordre de lecture dans le DOM, ni les rôles ARIA nécessaires pour des composants complexes comme une liste de sélection ou un onglet.
Un panneau en popover natif est-il automatiquement conforme au RGAA ?
Non. Le couple popover/popovertarget expose gratuitement l'état d'ouverture, mais les tests des critères 7.1 et 7.3 (nom, rôle, état restitués ; focus non perdu) doivent être vérifiés manuellement, notamment le comportement du focus à la fermeture.
Peut-on utiliser focusgroup en production aujourd'hui ?
Ce n'est pas recommandé en l'état. Le support est limité à Chrome 150 et des incohérences de restitution ont été observées avec NVDA et JAWS en mode curseur virtuel. À réserver à l'expérimentation, avec un repli JavaScript pour les autres navigateurs.
Quels critères RGAA sont concernés par ces nouvelles primitives ?
Principalement 7.1 (compatibilité du composant avec les technologies d'assistance) et 7.3 (contrôle au clavier et à la souris, non-perte du focus), ainsi que la thématique 12 Navigation lorsque le popover ou le focusgroup structure un menu ou une liste de liens.
Guides RGAA associés
Pour aller plus loin sur les sujets abordés dans cet article, consultez nos fiches techniques :
L'ordre de tabulation clavier doit être cohérent avec l'ordre de lecture visuel (l'absence de piège au clavier relève du critère 12.9).
Le focus clavier ne doit pas être masqué ou rendu invisible. L'indicateur de focus doit être clairement visible sur tous les éléments interactifs.
Chaque champ de formulaire doit avoir une étiquette (label) qui lui est liée explicitement.
Articles similaires
Votre site est-il conforme ?
Ne prenez pas de risques avec l'accessibilité. Lancez un audit complet de votre site en quelques minutes et obtenez un rapport détaillé des corrections à apporter.