Qu'est-ce que ARIA ?

ARIA (Accessible Rich Internet Applications) est une spécification du W3C qui permet d'améliorer l'accessibilité des applications web riches et des composants dynamiques.

🏷️ Rôles

Définissent ce qu'est un élément (button, navigation, alert...)

role="button"

📊 États

Décrivent l'état actuel d'un élément (checked, expanded, disabled...)

aria-expanded="true"

🔧 Propriétés

Fournissent des informations supplémentaires (label, describedby, controls...)

aria-label="Menu principal"

⚠️ Règle d'or d'ARIA

Ne pas utiliser ARIA si vous pouvez utiliser HTML natif

Formulaires avec attributs ARIA

Mauvais exemple

Formulaire sans ARIA

❌ Formulaire inaccessible sans attributs ARIA appropriés :

<!-- Mauvais : pas de label, pas de description -->
<input type="text" placeholder="Votre email">

<!-- Mauvais : icône non accessible -->
<button>
  <span class="icon">🔍</span>
</button>

<!-- Mauvais : erreur non associée, pas d'autocomplete -->
<input type="password">
<div class="error">Mot de passe trop court</div>
Mot de passe trop court
J'accepte les conditions d'utilisation

Bon exemple

Formulaire avec ARIA

✅ Formulaire accessible avec attributs ARIA appropriés :

<!-- Bon : aria-label pour champ sans label visible -->
<input
  type="text"
  aria-label="Adresse email (obligatoire)"
  aria-describedby="email-desc"
  aria-required="true">
<span id="email-desc">Format: nom@exemple.com</span>

<!-- Bon : bouton avec aria-label -->
<button aria-label="Envoyer le formulaire">
  <span aria-hidden="true">🔍</span>
</button>

<!-- Bon : erreur associée avec aria-describedby -->
<input
  type="password"
  aria-label="Mot de passe (8 caractères minimum)"
  aria-invalid="true"
  aria-describedby="pwd-error"
  autocomplete="new-password">
<div id="pwd-error" role="alert">
  Le mot de passe doit contenir au moins 8 caractères
</div>
Format: nom@exemple.com
Minimum 8 caractères avec chiffres et lettres
Options de notification
Recevez les mises à jour importantes par email
Recevez les alertes urgentes par SMS
Attributs ARIA utilisés :
  • aria-label : Fournit un label accessible
  • aria-describedby : Associe une description détaillée
  • aria-required : Indique un champ obligatoire
  • aria-invalid : Signale un champ invalide
  • aria-labelledby : Référence un label existant
  • role="alert" : Annonce immédiatement les erreurs
  • aria-hidden : Cache les éléments décoratifs
  • aria-live : Annonce les changements dynamiques

Explication : Les attributs ARIA enrichissent les formulaires en fournissant des labels, descriptions et états aux technologies d'assistance.

Accordéon accessible

Mauvais exemple

Sans attributs ARIA

Qu'est-ce que l'accessibilité web ?+
Pourquoi est-ce important ?+
Comment commencer ?+
<!-- Bad: No ARIA attributes, no keyboard navigation -->
<div class="accordion-header" @click="toggle">
  <span>Title</span>
  <span>+</span>
</div>
<div v-if="open">
  Content
</div>

Bon exemple

Avec ARIA correct

<!-- Good: Complete ARIA with keyboard navigation -->
<button
  id="accordion-button-1"
  aria-expanded="false"
  aria-controls="panel-1"
  @click="toggle"
  @keydown.enter="toggle"
>
  Title
</button>
<div
  id="panel-1"
  role="region"
  aria-labelledby="accordion-button-1"
  :hidden="!open"
>
  Content
</div>

Explication : Un accordéon doit utiliser les attributs ARIA appropriés, supporter la navigation clavier et annoncer les changements d'état.

Tabindex et navigation clavier

L'attribut tabindex contrôle si un élément peut recevoir le focus clavier et dans quel ordre.

✅ tabindex="0"

L'élément est focusable dans l'ordre naturel du DOM

tabindex="0"
<!-- Good: Interactive element focusable -->
<div role="button" aria-label="Custom action" tabindex="0">
  Custom button
</div>

⚠️ tabindex="-1"

Focusable par JavaScript mais pas par Tab

tabindex="-1"
<!-- Good: For programmatic focus -->
<div role="alert" aria-live="assertive" tabindex="-1">
  Error message
</div>

❌ tabindex > 0

Change l'ordre de navigation (à éviter !)

tabindex="5"
<!-- Bad: Breaks natural tab order -->
<button tabindex="3">Third</button>
<button tabindex="1">First</button>
<button tabindex="2">Second</button>

📋 Bonnes pratiques tabindex

  • Utilisez tabindex="0" pour rendre les éléments custom interactifs focusables
  • Utilisez tabindex="-1" pour le focus programmatique (modals, alerts)
  • N'utilisez JAMAIS de valeurs positives - respectez l'ordre du DOM
  • Les éléments natifs interactifs (<button>, <a>, <input>) n'ont pas besoin de tabindex

🎯 Exemples interactifs

Testez la navigation au clavier (Tab/Shift+Tab) avec ces éléments :

✅ Éléments focusables

Lien
Bouton custom (div)

❌ Éléments non-focusables

Texte simple (div)
Texte inline (span)

Paragraphe

💡 Conseils pour tester

  • Utilisez Tab pour naviguer vers l'avant
  • Utilisez Shift + Tab pour naviguer vers l'arrière
  • Utilisez Espace ou Entrée pour activer les éléments
  • Observez l'indicateur de focus (contour bleu)
  • Notez quels éléments peuvent ou ne peuvent pas recevoir le focus

Menu déroulant accessible

Mauvais exemple

Bon exemple

Explication : Un menu déroulant doit supporter la navigation clavier, fermer avec Échap, et maintenir le focus de manière appropriée.

Galerie d'images accessible

Mauvais exemple

Bon exemple

Explication : Une galerie d'images doit permettre la navigation au clavier et fournir des descriptions contextuelles pour chaque image. Le pattern ARIA tablist/tab/tabpanel est parfait pour ce cas d'usage.

Tableau triable accessible

Mauvais exemple

Nom ↑Email Rôle Statut
Alice Martinalice@example.comAdminActif
Bob Dupontbob@example.comUtilisateurInactif
Charlie Leroycharlie@example.comModérateurActif
Diana Moreaudiana@example.comUtilisateurSuspendu

Bon exemple

Alice Martinalice@example.comAdminActif
Bob Dupontbob@example.comUtilisateurInactif
Charlie Leroycharlie@example.comModérateurActif
Diana Moreaudiana@example.comUtilisateurSuspendu
Cliquez sur les en-têtes de colonnes pour trier le tableau. Utilisez Tab pour naviguer entre les boutons de tri.

Explication : Un tableau triable doit indiquer l'état de tri courant, permettre la navigation clavier, et annoncer les changements aux lecteurs d'écran.

Zones dynamiques aria-live

Mauvais exemple

Sans aria-live

Les changements ne sont pas annoncés

<!-- Mauvais : pas d'attribut aria-live -->
<div class="status-banner">
  <p></p>
</div>

Compteur : 0

Problèmes :

  • Les changements ne sont pas annoncés
  • Les utilisateurs de lecteurs d'écran ne savent pas que le contenu a changé
  • Aucune indication de l'importance du message

Bon exemple

Avec aria-live approprié

Les changements sont annoncés selon leur priorité

<!-- Bon : avec aria-live="polite" pour informations -->
<div
  class="status-banner"
  aria-live="polite"
  aria-atomic="true"
  role="status"
>
  <p>Information : Données mises à jour</p>
</div>

<!-- Bon : avec aria-live="assertive" pour alertes -->
<div
  class="alert-banner"
  aria-live="assertive"
  aria-atomic="true"
  role="alert"
>
  <p>Attention : Action requise immédiatement</p>
</div>

Zone polite (informations)

Avantages :

  • Les messages importants interrompent avec aria-live="assertive"
  • Les messages informatifs attendent avec aria-live="polite"
  • aria-atomic="true" annonce tout le contenu de la région
  • Les rôles appropriés (status, alert) donnent plus de contexte

Explication : Les zones aria-live permettent d'annoncer des changements de contenu aux lecteurs d'écran. 'polite' attend la fin de l'annonce en cours, 'assertive' interrompt immédiatement.

Boutons avec icônes accessibles

Mauvais exemple

Boutons sans description

Ces boutons n'ont aucune indication textuelle :

Problèmes :
  • Les lecteurs d'écran annoncent juste "bouton"
  • Impossible de savoir l'action sans voir l'icône
  • Les émojis peuvent être mal interprétés
  • Aucun tooltip au survol

Bon exemple

Boutons accessibles

Plusieurs approches pour rendre les icônes accessibles :

1. Avec aria-label
2. Avec texte visible
3. Avec texte masqué visuellement
Bonnes pratiques :
  • Toujours fournir un texte alternatif (aria-label, texte masqué, ou texte visible)
  • Utiliser aria-hidden="true" sur les icônes décoratives
  • Ajouter des tooltips avec l'attribut title
  • Préférer le texte visible quand l'espace le permet

Explication : Les boutons qui contiennent uniquement des icônes doivent avoir un aria-label ou du texte masqué visuellement pour être compris par les lecteurs d'écran.

Combobox / Recherche avec suggestions

Mauvais exemple

Sans ARIA ni navigation clavier

Bon exemple

Avec ARIA et navigation clavier

0 résultat(s) disponible(s)

Explication : Une recherche avec suggestions (combobox) doit être navigable au clavier, annoncer les résultats et permettre la sélection.

Notifications Toast (Live Regions)

Mauvais exemple

Sans aria-live

❌ Les notifications ne sont pas annoncées aux lecteurs d'écran

<!-- Mauvais : pas annoncé aux lecteurs d'écran -->
<div v-if="showToast" class="toast">
  Votre demande a été enregistrée
</div>

Bon exemple

Avec aria-live approprié

✅ Les notifications sont correctement annoncées

<!-- Bon : notification info (polite) -->
<div
  v-if="showToast"
  role="status"
  aria-live="polite"
  aria-atomic="true"
  class="toast"
>
  <p>Votre demande a été enregistrée</p>
  <button @click="dismiss" aria-label="Fermer notification">✕</button>
</div>

<!-- Bon : alerte erreur (assertive) -->
<div
  v-if="showError"
  role="alert"
  aria-live="assertive"
  aria-atomic="true"
  class="toast error"
>
  <p>Erreur : action impossible à exécuter</p>
  <button @click="dismiss" aria-label="Fermer alerte">✕</button>
</div>
Différences :
  • role="status" + aria-live="polite" : Pour les notifications informatives, n'interrompt pas la lecture en cours
  • role="alert" + aria-live="assertive" : Pour les erreurs critiques, interrompt immédiatement
  • aria-atomic="true" : Annonce tout le contenu de la notification

Explication : Les notifications dynamiques doivent être annoncées aux lecteurs d'écran sans voler le focus. Utilisez role='status' pour les infos et role='alert' pour les erreurs.