tabpanel
Désigne le panneau de contenu associé à un onglet. Chaque tabpanel est nommé par son onglet via aria-labelledby ; l'onglet référence le panneau via aria-controls. Affichez un seul panneau à la fois ; masquez les autres avec l'attribut hidden.
Quand l’utiliser
Sur le conteneur qui détient le contenu d’un onglet. Associez chaque tabpanel à son onglet via aria-labelledby (pointant vers l’identifiant de l’onglet). L’onglet, à son tour, pointe vers le panneau avec aria-controls. Masquez les panneaux inactifs avec l’attribut hidden — pas seulement display: none via CSS — afin que l’arbre d’accessibilité reflète l’état visuel.
Si le panneau contient du contenu interactif (un formulaire, une liste de liens), vous pouvez le rendre focalisable avec tabindex="0". Ainsi, après l’activation d’un onglet, la prochaine touche Tab atterrit à l’intérieur du panneau.
Si le panneau contient une seule région focalisable — par exemple un grand titre suivi d’un contenu — tabindex="0" sur le panneau est suffisant. Si le panneau est rempli de contrôles focalisables, l’utilisateur y accèdera directement avec Tab et le tabindex est facultatif.
Erreurs courantes
- Tabpanel masqué via CSS mais pas via l’attribut
hidden. Les lecteurs d’écran peuvent encore exposer son contenu. - Tabpanel sans
aria-labelledby— annoncé simplement comme « panneau d’onglet » sans nom. - L’onglet pointe vers un identifiant de tabpanel via
aria-controlsmais le panneau ne pointe pas en retour viaaria-labelledby. L’association doit être réciproque. - Tous les tabpanels sont dans le DOM avec
display: nonecommuté dynamiquement, mais sans attributhidden. Les auditeurs signalent l’incohérence. role="tabpanel"appliqué à un panneau qui n’est PAS associé à unrole="tab"— tabpanel orphelin.
Exemple
<div role="tablist" aria-label="Settings">
<button role="tab" id="t-account" aria-selected="true" aria-controls="p-account" tabindex="0">Account</button>
<button role="tab" id="t-billing" aria-selected="false" aria-controls="p-billing" tabindex="-1">Billing</button>
</div>
<section role="tabpanel" id="p-account" aria-labelledby="t-account" tabindex="0">
<h2>Account</h2>
<p>…</p>
</section>
<section role="tabpanel" id="p-billing" aria-labelledby="t-billing" tabindex="0" hidden>
<h2>Billing</h2>
<p>…</p>
</section>