Technique11 mai 20266 min

aria-describedby : à quoi il sert et quand l'utiliser

En Bref : L'essentiel à retenir

  • aria-describedby lie un élément à un texte descriptif situé ailleurs dans la page, lu après le nom et rôle par les lecteurs d'écran.
  • Contrairement à aria-label qui remplace le nom, aria-describedby ajoute des informations contextuelles supplémentaires.
  • Les descriptions peuvent être masquées visuellement tout en restant accessibles aux technologies d'assistance.
  • Utilisez aria-describedby pour les instructions de champs, messages d'erreur, hints et descriptions longues.
ARIAFormulairesRGAAHTMLDev

L'attribut aria-describedby est un outil puissant pour enrichir l'expérience des utilisateurs de technologies d'assistance. Il permet d'associer des descriptions supplémentaires à des éléments, offrant un contexte que le nom accessible seul ne peut pas fournir.

Comprendre aria-describedby

Définition

aria-describedby établit une relation entre un élément et un ou plusieurs autres éléments qui le décrivent. La description est lue par les lecteurs d'écran après le nom et le rôle de l'élément.

CODE
<input type="password" id="pwd"
       aria-describedby="pwd-hint">
<p id="pwd-hint">
  Le mot de passe doit contenir au moins 12 caractères.
</p>

Annonce du lecteur d'écran : "Mot de passe, champ de saisie. Le mot de passe doit contenir au moins 12 caractères."

Différence avec aria-labelledby

AttributRôleLu
aria-labelledbyDéfinit le nom accessibleEn premier
aria-describedbyAjoute une descriptionAprès le nom et rôle
CODE
<!-- aria-labelledby définit le nom -->
<button aria-labelledby="btn-label">
  <svg>...</svg>
</button>
<span id="btn-label">Fermer la modale</span>

<!-- aria-describedby ajoute du contexte -->
<button aria-describedby="btn-desc">
  Supprimer
</button>
<span id="btn-desc">Cette action est irréversible</span>

Note

aria-labelledby et aria-describedby peuvent être utilisés ensemble sur le même élément pour des cas complexes.

Cas d'usage courants

1. Instructions de champs de formulaire

Le cas le plus fréquent : fournir des instructions pour remplir un champ.

CODE
<label for="email">Adresse email</label>
<input type="email" id="email"
       aria-describedby="email-help">
<p id="email-help">
  Format attendu : votre.nom@exemple.com
</p>

2. Messages d'erreur

Associez les messages d'erreur aux champs concernés :

CODE
<label for="telephone">Téléphone</label>
<input type="tel" id="telephone"
       aria-invalid="true"
       aria-describedby="tel-error">
<p id="tel-error" class="error">
  Le numéro doit contenir 10 chiffres (ex: 0612345678)
</p>

L'attribut aria-invalid="true" signale l'erreur, et aria-describedby pointe vers l'explication.

3. Descriptions de liens

Pour les liens dont l'intitulé seul est ambigu :

CODE
<a href="/produit/123" aria-describedby="prod-desc">
  Voir le produit
</a>
<span id="prod-desc" class="sr-only">
  T-shirt bleu marine taille M - 29,99 EUR
</span>

4. Boutons d'action

Expliquez les conséquences d'une action :

CODE
<button type="button"
        aria-describedby="delete-warning">
  Supprimer mon compte
</button>
<p id="delete-warning">
  Cette action supprimera définitivement toutes vos données.
</p>

5. Icônes et symboles

Décrivez la signification d'indicateurs visuels :

CODE
<span class="status-badge status-online"
      aria-describedby="status-desc">
  Jean Dupont
</span>
<span id="status-desc" class="sr-only">
  Actuellement en ligne
</span>

6. Modales et dialogues

Fournissez un contexte à l'ouverture :

CODE
<div role="dialog"
     aria-modal="true"
     aria-labelledby="dialog-title"
     aria-describedby="dialog-desc">
  <h2 id="dialog-title">Confirmer la suppression</h2>
  <p id="dialog-desc">
    Vous êtes sur le point de supprimer 5 fichiers.
    Cette action est irréversible.
  </p>
  <button>Annuler</button>
  <button>Confirmer</button>
</div>

Descriptions multiples

aria-describedby accepte plusieurs IDs séparés par des espaces. Les descriptions sont lues dans l'ordre :

CODE
<input type="password" id="new-pwd"
       aria-describedby="pwd-rules pwd-error">

<p id="pwd-rules">
  Minimum 12 caractères, une majuscule et un chiffre.
</p>
<p id="pwd-error" class="error" hidden>
  Le mot de passe ne respecte pas les critères.
</p>

Astuce

N'abusez pas des descriptions multiples. Trop d'informations peuvent submerger l'utilisateur.

Descriptions masquées

Les éléments référencés par aria-describedby n'ont pas besoin d'être visibles. Vous pouvez les masquer visuellement tout en les gardant accessibles :

CODE
<button aria-describedby="hidden-desc">
  Télécharger
</button>
<span id="hidden-desc" class="sr-only">
  Fichier PDF de 2,5 Mo
</span>
CODE
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

Attention : display: none ou visibility: hidden masquent également le contenu aux technologies d'assistance. Utilisez la technique sr-only.

Ce que le RGAA en attend

Le référentiel ne prescrit aucun attribut : il fixe des résultats, et laisse le choix de la technique. Deux critères se satisfont couramment par aria-describedby.

Le critère 11.10 porte sur le contrôle de saisie. Quand un champ impose un format, une longueur ou une valeur attendue, l'information doit être disponible avant la saisie, pas seulement après l'échec. Une consigne rattachée au champ par aria-describedby répond exactement à ce besoin.

Le critère 11.11 va plus loin : quand la saisie échoue, l'utilisateur doit recevoir une suggestion qui lui permette de corriger. Un message générique du type « champ invalide » ne suffit pas ; c'est la combinaison de aria-invalid et d'une description explicite qui rend l'erreur exploitable.

Une nuance qui revient souvent en audit : ces critères ne sont pas satisfaits par la seule présence de l'attribut. Une description qui répète l'étiquette, ou qui reste vide au moment où l'erreur survient, laisse le critère en échec bien que le balisage soit formellement correct. Le critère 11.2 applique la même logique aux étiquettes : la pertinence se juge, elle ne se déclare pas.

Erreurs courantes à éviter

1. Références inexistantes

CODE
<!-- ERREUR : l'ID n'existe pas -->
<input aria-describedby="instructions">
<!-- Pas d'élément avec id="instructions" -->

Vérifiez toujours que les IDs référencés existent dans le DOM.

2. Descriptions redondantes

CODE
<!-- INUTILE : répète le label -->
<label for="nom">Votre nom</label>
<input id="nom" aria-describedby="nom-desc">
<p id="nom-desc">Entrez votre nom</p>

N'utilisez pas aria-describedby pour répéter ce qui est déjà dans le label.

3. Trop de descriptions

CODE
<!-- EXCESSIF -->
<input aria-describedby="desc1 desc2 desc3 desc4 desc5">

Limitez-vous à 2-3 descriptions maximum pour ne pas surcharger l'utilisateur.

4. Contenu dynamique mal géré

Si la description change après le focus initial, le changement n'est pas automatiquement annoncé. Utilisez aria-live si nécessaire :

CODE
<input id="field" aria-describedby="live-feedback">
<div id="live-feedback" aria-live="polite">
  <!-- Feedback dynamique -->
</div>

Quand utiliser aria-details au lieu de aria-describedby

Pour les descriptions longues et structurées (avec listes, tableaux, liens), préférez aria-details :

CODE
<img src="graphique.png"
     alt="Graphique des ventes"
     aria-details="graphique-data">

<details id="graphique-data">
  <summary>Données du graphique</summary>
  <table>
    <tr><th>Année</th><th>Ventes</th></tr>
    <tr><td>2024</td><td>100</td></tr>
    <tr><td>2025</td><td>150</td></tr>
  </table>
</details>

aria-details permet aux utilisateurs de naviguer dans le contenu structuré, contrairement à aria-describedby qui lit le texte de manière linéaire.

Compatibilité navigateurs et lecteurs d'écran

aria-describedby est bien pris en charge :

  • Tous les navigateurs modernes
  • NVDA, JAWS, VoiceOver, TalkBack
  • Support mobile complet

Intégration avec les frameworks

React

CODE
function PasswordField() {
  const [error, setError] = useState(null);

  return (
    <>
      <label htmlFor="pwd">Mot de passe</label>
      <input
        type="password"
        id="pwd"
        aria-describedby={error ? "pwd-error" : "pwd-hint"}
        aria-invalid={!!error}
      />
      <p id="pwd-hint">Minimum 12 caractères</p>
      {error && (
        <p id="pwd-error" className="error">{error}</p>
      )}
    </>
  );
}

Vue

CODE
<template>
  <label for="pwd">Mot de passe</label>
  <input
    type="password"
    id="pwd"
    :aria-describedby="hasError ? 'pwd-error' : 'pwd-hint'"
    :aria-invalid="hasError"
  />
  <p id="pwd-hint">Minimum 12 caractères</p>
  <p v-if="hasError" id="pwd-error" class="error">{{ errorMessage }}</p>
</template>

Checklist aria-describedby

Avant utilisation, vérifiez :

  • L'identifiant référencé existe réellement dans le DOM
  • La description apporte une information nouvelle (pas de redondance)
  • Le texte est concis et pertinent
  • Les descriptions masquées utilisent la technique sr-only (pas display:none)
  • Pas plus de 2-3 descriptions par élément
  • Les changements dynamiques sont gérés (aria-live si nécessaire)

Conclusion

aria-describedby est un attribut essentiel pour enrichir l'accessibilité de vos interfaces. Utilisé correctement, il fournit un contexte précieux aux utilisateurs de technologies d'assistance sans surcharger l'interface visuelle.

Pour le nommage proprement dit, qui est l'autre moitié du sujet, notre guide sur aria-label et aria-labelledby traite le choix entre les attributs et les conditions que le RGAA ajoute quand l'étiquette n'est pas visible.

Analysez un formulaire de votre site pour repérer les champs sans étiquette et les références d'identifiants qui pointent dans le vide : ce sont les deux défauts qu'un automate tranche seul. La pertinence de la consigne, elle, se relit.

Questions fréquentes

Quelle différence entre aria-describedby et aria-labelledby ?

aria-labelledby donne le nom accessible de l'élément, aria-describedby ajoute une description par-dessus ce nom. L'ordre de restitution le montre : le lecteur d'écran annonce d'abord le nom et le rôle, puis la description. Les deux se posent sur un même élément sans conflit, parce qu'ils ne répondent pas à la même question : l'un dit ce que c'est, l'autre ce qu'il faut savoir en plus.

La description doit-elle être visible à l'écran ?

Non, mais elle gagne presque toujours à l'être. Un élément référencé par aria-describedby peut être masqué visuellement avec une technique de type sr-only et rester restitué. En revanche, display: none et visibility: hidden le retirent aussi de l'arbre d'accessibilité : la description devient invisible pour tout le monde. Et une consigne de saisie utile aux lecteurs d'écran l'est généralement à tous.

aria-describedby est-il exigé par le RGAA ?

Le référentiel n'impose aucun attribut en particulier, il fixe des résultats. aria-describedby est l'une des façons de satisfaire le critère 11.10 sur le contrôle de saisie et le critère 11.11 sur les suggestions de correction, en rattachant une consigne ou un message d'erreur au champ concerné. D'autres techniques sont recevables, mais celle-ci est la plus robuste sur les formulaires.

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.