Aria-selected : exemples pratiques pour onglets et listes
En Bref : L'essentiel à retenir
- aria-selected indique l'élément actuellement sélectionné dans un groupe comme les onglets (tablist), listes (listbox) ou grilles interactives.
- Dans un tablist, l'onglet sélectionné a aria-selected="true" et tabindex="0", les autres ont aria-selected="false" et tabindex="-1".
- Pour les listbox multi-sélection, combinez aria-selected avec aria-multiselectable="true" sur le conteneur parent.
- Ne confondez pas aria-selected (sélection dans un groupe) avec aria-current (position actuelle dans une navigation).
L'attribut aria-selected communique l'état de sélection d'un élément au sein d'un groupe. Onglets, listes déroulantes personnalisées, tableaux interactifs : voici comment l'implémenter correctement avec des exemples concrets.
Comprendre aria-selected
aria-selected indique si un élément est actuellement sélectionné parmi un ensemble d'options :
true: l'élément est sélectionnéfalse: l'élément n'est pas sélectionné- Non défini : l'élément n'est pas sélectionnable
[!NOTE]
aria-selecteds'utilise sur des rôles spécifiques :option,tab,gridcell,row,treeitem. Ne l'utilisez pas sur des éléments quelconques.
Exemple 1 : système d'onglets
Les onglets (tabs) sont le cas d'usage le plus courant :
Structure HTML
<div class="tabs">
<div role="tablist" aria-label="Informations produit">
<button
role="tab"
id="tab-desc"
aria-selected="true"
aria-controls="panel-desc"
tabindex="0">
Description
</button>
<button
role="tab"
id="tab-specs"
aria-selected="false"
aria-controls="panel-specs"
tabindex="-1">
Caractéristiques
</button>
<button
role="tab"
id="tab-reviews"
aria-selected="false"
aria-controls="panel-reviews"
tabindex="-1">
Avis clients
</button>
</div>
<div
role="tabpanel"
id="panel-desc"
aria-labelledby="tab-desc"
tabindex="0">
<p>Description détaillée du produit...</p>
</div>
<div
role="tabpanel"
id="panel-specs"
aria-labelledby="tab-specs"
tabindex="0"
hidden>
<p>Spécifications techniques...</p>
</div>
<div
role="tabpanel"
id="panel-reviews"
aria-labelledby="tab-reviews"
tabindex="0"
hidden>
<p>Avis des clients...</p>
</div>
</div>
Points clés
| Attribut | Onglet actif | Onglets inactifs |
|---|---|---|
aria-selected | true | false |
tabindex | 0 | -1 |
Le tabindex="-1" sur les onglets inactifs permet la navigation par flèches sans que Tab passe par chaque onglet.
JavaScript d'activation
class TabSystem {
constructor(container) {
this.tabs = container.querySelectorAll('[role="tab"]');
this.panels = container.querySelectorAll('[role="tabpanel"]');
this.tabs.forEach(tab => {
tab.addEventListener('click', () => this.selectTab(tab));
tab.addEventListener('keydown', (e) => this.handleKeydown(e, tab));
});
}
selectTab(selectedTab) {
// Désélectionner tous les onglets
this.tabs.forEach(tab => {
tab.setAttribute('aria-selected', 'false');
tab.setAttribute('tabindex', '-1');
});
// Masquer tous les panneaux
this.panels.forEach(panel => panel.hidden = true);
// Sélectionner l'onglet actif
selectedTab.setAttribute('aria-selected', 'true');
selectedTab.setAttribute('tabindex', '0');
selectedTab.focus();
// Afficher le panneau correspondant
const panelId = selectedTab.getAttribute('aria-controls');
document.getElementById(panelId).hidden = false;
}
handleKeydown(event, currentTab) {
const index = Array.from(this.tabs).indexOf(currentTab);
let newIndex;
switch (event.key) {
case 'ArrowRight':
newIndex = (index + 1) % this.tabs.length;
this.selectTab(this.tabs[newIndex]);
break;
case 'ArrowLeft':
newIndex = (index - 1 + this.tabs.length) % this.tabs.length;
this.selectTab(this.tabs[newIndex]);
break;
case 'Home':
this.selectTab(this.tabs[0]);
break;
case 'End':
this.selectTab(this.tabs[this.tabs.length - 1]);
break;
}
}
}
Exemple 2 : listbox (liste personnalisée)
Pour une liste déroulante personnalisée remplaçant un <select> :
Sélection simple
<label id="color-label">Couleur préférée</label>
<div
role="listbox"
aria-labelledby="color-label"
tabindex="0">
<div role="option" id="opt-red" aria-selected="true">Rouge</div>
<div role="option" id="opt-blue" aria-selected="false">Bleu</div>
<div role="option" id="opt-green" aria-selected="false">Vert</div>
</div>
Sélection multiple
Ajoutez aria-multiselectable="true" sur le conteneur :
<label id="tags-label">Tags (sélection multiple)</label>
<div
role="listbox"
aria-labelledby="tags-label"
aria-multiselectable="true"
tabindex="0">
<div role="option" aria-selected="true">Accessibilité</div>
<div role="option" aria-selected="true">RGAA</div>
<div role="option" aria-selected="false">Design</div>
<div role="option" aria-selected="false">Développement</div>
</div>
[!TIP] Pour les sélections multiples, certains design systems préfèrent
aria-checkedàaria-selected. Les deux sont validés, mais restez cohérent dans votre application.
Exemple 3 : grille sélectionnable
Pour un tableau dont les lignes sont sélectionnables :
<table role="grid" aria-label="Liste des utilisateurs">
<thead>
<tr>
<th scope="col">Nom</th>
<th scope="col">Email</th>
<th scope="col">Rôle</th>
</tr>
</thead>
<tbody>
<tr role="row" aria-selected="true" tabindex="0">
<td role="gridcell">Marie Dupont</td>
<td role="gridcell">marie@example.com</td>
<td role="gridcell">Admin</td>
</tr>
<tr role="row" aria-selected="false" tabindex="-1">
<td role="gridcell">Jean Martin</td>
<td role="gridcell">jean@example.com</td>
<td role="gridcell">Éditeur</td>
</tr>
</tbody>
</table>
Le lecteur d'écran annoncera : "Marie Dupont, sélectionné, ligne 1 sur 2".
aria-selected vs aria-current
Ces attributs sont souvent confondus :
| Attribut | Usage | Exemple |
|---|---|---|
aria-selected | Sélection dans un widget | Onglet actif, option de liste |
aria-current | Position actuelle | Page courante dans un menu |
<!-- Navigation : aria-current -->
<nav>
<a href="/" aria-current="page">Accueil</a>
<a href="/produits">Produits</a>
</nav>
<!-- Onglets : aria-selected -->
<div role="tablist">
<button role="tab" aria-selected="true">Tab 1</button>
<button role="tab" aria-selected="false">Tab 2</button>
</div>
Consultez notre article sur aria-current pour la navigation.
Navigation clavier attendue
Onglets (tablist)
| Touche | Action |
|---|---|
| Tab | Entre dans le tablist, focus sur l'onglet actif |
| Flèches | Change l'onglet sélectionné |
| Home/End | Premier/dernier onglet |
Listbox
| Touche | Action |
|---|---|
| Tab | Entre dans la listbox |
| Flèches haut/bas | Déplace le focus (et sélectionne en mode simple) |
| Espace | Bascule la sélection (mode multi) |
| Ctrl+A | Sélectionne tout (mode multi) |
Erreurs courantes
1. Oublier de synchroniser tabindex
<!-- Incohérent : aria-selected et tabindex désynchronisés -->
<button role="tab" aria-selected="true" tabindex="-1">Tab 1</button>
<!-- Correct -->
<button role="tab" aria-selected="true" tabindex="0">Tab 1</button>
2. Utiliser aria-selected sur des éléments non adaptés
<!-- Incorrect : div n'est pas un rôle sélectionnable -->
<div aria-selected="true">Option</div>
<!-- Correct : avec le rôle approprié -->
<div role="option" aria-selected="true">Option</div>
3. Pas de valeur false sur les non-sélectionnés
<!-- Ambigu : les autres options sont-elles sélectionnables ? -->
<div role="option" aria-selected="true">Option 1</div>
<div role="option">Option 2</div>
<!-- Explicite -->
<div role="option" aria-selected="true">Option 1</div>
<div role="option" aria-selected="false">Option 2</div>
Indicateur visuel de sélection
Ne vous fiez pas à la couleur seule. Combinez :
[role="tab"][aria-selected="true"] {
background: #005fcc;
color: white;
border-bottom: 3px solid #003d80;
}
[role="option"][aria-selected="true"]::before {
content: "✓ ";
}
L'icône de coche renforce l'état pour les utilisateurs daltoniens.
Critères RGAA concernés
| Critère | Exigence |
|---|---|
| 7.1 | Scripts compatibles avec les technologies d'assistance |
| 7.3 | Composants utilisables au clavier et à la souris |
| 3.1 | Information transmise autrement que par la couleur |
Conclusion
aria-selected est essentiel pour rendre vos widgets de sélection accessibles. Respectez les rôles ARIA appropriés, synchronisez tabindex avec l'état de sélection, et implémentez la navigation clavier complète. Vos utilisateurs de technologies d'assistance pourront alors interagir efficacement avec vos interfaces.
Testez l'accessibilité de vos composants avec RGAA Checker : notre outil vérifie les attributs ARIA et leur cohérence sur l'ensemble de vos pages.
Guides RGAA associés
Pour aller plus loin sur les sujets abordés dans cet article, consultez nos fiches techniques :
Chaque champ de formulaire doit avoir une étiquette (label) qui lui est liée explicitement.
Chaque image porteuse d'information doit avoir une alternative textuelle pertinente via l'attribut alt. Les images décoratives doivent avoir un attribut alt vide.
Pour chaque tableau de données, chaque en-tête de colonne et chaque en-tête de ligne doivent être correctement déclarés avec la balise <th>.
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.