Aller au contenu principal
Technique11 mars 20267 min

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).
ARIAOngletsListesJavaScriptAccessibilité

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-selected s'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

CODE
<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

AttributOnglet actifOnglets inactifs
aria-selectedtruefalse
tabindex0-1

Le tabindex="-1" sur les onglets inactifs permet la navigation par flèches sans que Tab passe par chaque onglet.

JavaScript d'activation

CODE
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

CODE
<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 :

CODE
<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 :

CODE
<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 :

AttributUsageExemple
aria-selectedSélection dans un widgetOnglet actif, option de liste
aria-currentPosition actuellePage courante dans un menu
CODE
<!-- 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.

Onglets (tablist)

ToucheAction
TabEntre dans le tablist, focus sur l'onglet actif
FlèchesChange l'onglet sélectionné
Home/EndPremier/dernier onglet

Listbox

ToucheAction
TabEntre dans la listbox
Flèches haut/basDéplace le focus (et sélectionne en mode simple)
EspaceBascule la sélection (mode multi)
Ctrl+ASélectionne tout (mode multi)

Erreurs courantes

1. Oublier de synchroniser tabindex

CODE
<!-- 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

CODE
<!-- 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

CODE
<!-- 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 :

CODE
[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èreExigence
7.1Scripts compatibles avec les technologies d'assistance
7.3Composants utilisables au clavier et à la souris
3.1Information 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.

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.