Tooltips accessibles : bonnes pratiques et implémentation
En Bref : L'essentiel à retenir
- Les tooltips doivent apparaître au focus clavier et au survol souris pour respecter le critère WCAG 1.4.13.
- Un tooltip conforme doit être rejetable (Echap), survolable et persistant tant que le déclencheur est actif.
- L'attribut aria-describedby lie le tooltip à son déclencheur pour les lecteurs d'écran.
- Les tooltips ne doivent contenir que des informations non essentielles car ils peuvent ne jamais être lus.
Les tooltips (ou infobulles) semblent être des composants simples, mais leur accessibilité est souvent négligée. Entre l'impossibilité d'y accéder au clavier, le contenu qui disparaît trop vite et l'incompatibilité avec les technologies d'assistance, les problèmes sont fréquents. Voici comment implémenter des tooltips véritablement accessibles.
Ce qu'exigent les WCAG pour les tooltips
Le critère WCAG 1.4.13 - Contenu au survol ou au focus (niveau AA) définit trois exigences fondamentales pour tout contenu apparaissant au survol ou au focus, y compris les tooltips.
Les trois règles d'or
- Rejetable : L'utilisateur peut fermer le tooltip sans déplacer le pointeur ou le focus (généralement avec Echap)
- Survolable : L'utilisateur peut déplacer son pointeur sur le tooltip sans qu'il disparaisse
- Persistant : Le tooltip reste visible tant que le déclencheur est survolé/focalisé
[!NOTE] Ces exigences ne s'appliquent pas si le tooltip est contrôlé par l'agent utilisateur (attribut
titlenatif) ou s'il ne masque pas d'autre contenu.
Tooltip vs Toggletip : quelle différence ?
Le tooltip classique
Un tooltip apparaît automatiquement au survol ou au focus et fournit une description supplémentaire d'un élément. Il utilise aria-describedby :
<button aria-describedby="tooltip-aide">
Sauvegarder
</button>
<div id="tooltip-aide" role="tooltip" hidden>
Enregistre vos modifications (Ctrl+S)
</div>
Le toggletip
Un toggletip s'ouvre sur une action explicite (clic) et peut contenir du contenu plus riche. C'est une meilleure option quand le contenu est essentiel ou complexe :
<button aria-expanded="false" aria-controls="info-panel">
<span aria-hidden="true">?</span>
<span class="sr-only">Plus d'informations</span>
</button>
<div id="info-panel" hidden>
Contenu détaillé avec liens possibles...
</div>
[!TIP] Privilégiez les toggletips pour les informations importantes. Les tooltips risquent de ne jamais être vus par certains utilisateurs.
Implémentation accessible d'un tooltip
Structure HTML
<div class="tooltip-container">
<button
class="tooltip-trigger"
aria-describedby="mon-tooltip"
>
<svg aria-hidden="true"><!-- icône --></svg>
<span class="sr-only">Aide</span>
</button>
<div
id="mon-tooltip"
role="tooltip"
class="tooltip"
>
Texte d'aide supplémentaire
</div>
</div>
Rôle ARIA et aria-describedby
role="tooltip": Identifie sémantiquement l'élément comme un tooltip (impact limité mais recommandé)aria-describedby: Relie le tooltip à son déclencheur pour les lecteurs d'écran
Le lecteur d'écran annoncera d'abord le nom accessible du bouton, puis après une pause, le contenu référencé par aria-describedby.
CSS pour l'affichage
.tooltip {
position: absolute;
opacity: 0;
visibility: hidden;
transition: opacity 0.2s;
/* Positionnement selon vos besoins */
}
/* Affichage au survol */
.tooltip-container:hover .tooltip,
/* Affichage au focus */
.tooltip-trigger:focus + .tooltip,
.tooltip-trigger:focus-within + .tooltip {
opacity: 1;
visibility: visible;
}
/* Le tooltip reste visible quand on le survole */
.tooltip:hover {
opacity: 1;
visibility: visible;
}
JavaScript pour la gestion complète
class AccessibleTooltip {
constructor(container) {
this.container = container;
this.trigger = container.querySelector('.tooltip-trigger');
this.tooltip = container.querySelector('.tooltip');
this.init();
}
init() {
// Affichage au focus
this.trigger.addEventListener('focus', () => this.show());
this.trigger.addEventListener('blur', () => this.hide());
// Gestion de la touche Echap (rejetable)
this.trigger.addEventListener('keydown', (e) => {
if (e.key === 'Escape') {
this.hide();
}
});
// Maintien au survol du tooltip (survolable)
this.tooltip.addEventListener('mouseenter', () => this.show());
this.tooltip.addEventListener('mouseleave', () => this.hide());
}
show() {
this.tooltip.classList.add('visible');
}
hide() {
this.tooltip.classList.remove('visible');
}
}
Ce que les tooltips ne doivent PAS contenir
Contenu essentiel
Les tooltips doivent contenir uniquement des informations complémentaires et non essentielles. Le meilleur tooltip est celui dont le contenu pourrait ne jamais être lu sans impacter la compréhension.
Éléments interactifs
Un tooltip ne peut pas contenir de liens, boutons ou champs de formulaire car :
- Il ne reçoit jamais le focus clavier
- Il disparaît quand l'utilisateur essaie de l'atteindre
- Son contenu n'est pas dans l'ordre de tabulation
Pour du contenu interactif, utilisez un toggletip ou une modale.
Contenu trop long
Si vous avez besoin de plusieurs paragraphes, ce n'est plus un tooltip. Envisagez une modale, un panneau latéral ou du contenu visible en permanence.
L'attribut title : pourquoi l'éviter
L'attribut HTML title génère un tooltip natif mais pose de nombreux problèmes d'accessibilité :
- Pas d'accès clavier : Le tooltip n'apparaît qu'au survol souris
- Lecture incohérente : Tous les lecteurs d'écran ne le lisent pas par défaut
- Impossible à survoler : Disparaît dès qu'on déplace la souris
- Pas de style possible : Apparence déterminée par le navigateur
- Inaccessible sur mobile : Pas de concept de survol sur écrans tactiles
[!NOTE] Le seul usage acceptable de
titleest sur les<iframe>pour fournir un titre accessible, et même là,aria-labelest souvent préférable.
Cas d'usage légitimes des tooltips
Icônes sans texte visible
<button aria-describedby="tooltip-supprimer">
<svg aria-hidden="true"><!-- icône corbeille --></svg>
<span class="sr-only">Supprimer</span>
</button>
<div id="tooltip-supprimer" role="tooltip">
Supprimer cet élément
</div>
Notez que le bouton a déjà un nom accessible via le span.sr-only. Le tooltip est un complément visuel, pas une nécessité.
Abréviations et termes techniques
<span
tabindex="0"
aria-describedby="def-rgaa"
class="term-with-tooltip"
>
RGAA
</span>
<div id="def-rgaa" role="tooltip">
Référentiel général d'amélioration de l'accessibilité
</div>
Le tabindex="0" rend le terme focusable au clavier pour déclencher le tooltip.
Raccourcis clavier
<button aria-describedby="shortcut-save">
Enregistrer
</button>
<div id="shortcut-save" role="tooltip">
Raccourci : Ctrl+S
</div>
Alternatives aux tooltips
Avant d'implémenter un tooltip, demandez-vous si une alternative ne serait pas plus appropriée :
| Situation | Alternative recommandée |
|---|---|
| Information essentielle | Texte visible en permanence |
| Contenu détaillé | Panneau déroulant ou modale |
| Aide contextuelle | Lien vers une page d'aide |
| Définition de terme | Élément <abbr> avec texte visible |
| Actions sur icônes | Texte visible à côté de l'icône |
Test d'accessibilité des tooltips
Pour valider l'accessibilité de vos tooltips :
- Navigation clavier : Le tooltip apparaît-il au focus sur le déclencheur ?
- Touche Echap : Le tooltip se ferme-t-il avec Echap ?
- Survol du tooltip : Peut-on déplacer la souris sur le tooltip sans qu'il disparaisse ?
- Lecteur d'écran : Le contenu est-il bien annoncé via
aria-describedby? - Mobile : Y a-t-il une alternative tactile ?
Vérifiez l'ensemble de votre interface avec notre outil d'audit RGAA.
Conclusion
Les tooltips accessibles nécessitent une implémentation soignée qui va bien au-delà d'un simple effet CSS au survol. En respectant les trois critères du WCAG 1.4.13 (rejetable, survolable, persistant) et en utilisant correctement aria-describedby, vous offrez une expérience cohérente à tous les utilisateurs.
Cependant, gardez à l'esprit que le meilleur tooltip est souvent celui qu'on n'a pas besoin de créer. Si l'information est importante, rendez-la visible pour tous.
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.
L'intitulé de chaque lien doit être explicite et permettre de comprendre la destination ou la fonction du lien, même hors contexte.
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.