RGAA Lab

Composants accessibles

Les SVG et les icônes

Un SVG en ligne n'a pas d'attribut alt : son nom et son rôle se déclarent, ou n'existent pas. Trois situations à distinguer — l'icône décorative, l'icône seule dans un bouton, le SVG informatif autonome.

4 critères RGAA en jeu

Essayez-les

Critère 1.1 — Alternative textuelle des images

Les quatre icônes se ressemblent, et aucune ne se comporte pareil. Changez le statut, puis lancez l’inspection : le nom du premier bouton vient de son texte, celui du troisième de son aria-label, celui de l’icône de statut de son aria-label à elle — et le second traîne un mot que personne n’a demandé.

Cette démo existe aussi en page autonome.

L’erreur courante

Un bouton qui ne contient qu’un SVG, et rien pour le nommer.

<!-- À ne pas faire -->
<button type="button" onclick="fermer()">
	<svg viewBox="0 0 20 20" width="16" height="16">
		<path d="M5 5l10 10M15 5L5 15" stroke="currentColor" stroke-width="2" />
	</svg>
</button>

Le lecteur d’écran annonce « bouton ». Pas « fermer », pas « croix » : rien. L’utilisateur sait qu’il y a quelque chose à actionner, jamais quoi — et l’obstacle est total, puisqu’aucun contexte ne le rattrape.

Le réflexe est de mettre l’alternative sur le dessin. C’est l’erreur suivante : le nom d’un bouton ne se cherche pas dans son icône. Le glossaire du référentiel est explicite — lorsqu’un <button> ne contient qu’une image, l’alternative de l’image est l’intitulé du bouton.

Trois variantes, moins spectaculaires et plus fréquentes :

  • L’icône décorative qui a gardé son <title>. L’outil de dessin l’a écrit, personne ne l’a retiré : le bouton s’appelle « disquette Enregistrer » au lieu d’« Enregistrer », et une infobulle parasite s’ouvre au survol.
  • title="Fermer" sur le bouton, sans autre nom. L’attribut title n’est restitué ni au clavier, ni au toucher, ni par tous les lecteurs d’écran. Il complète un nom, il n’en tient pas lieu.
  • Le SVG informatif avec un <title> mais sans role="img". Le rôle implicite d’un <svg> varie d’un navigateur à l’autre ; sans rôle explicite, l’image peut n’être annoncée nulle part. Le test 1.1.5 demande les deux.

Le code, pas à pas

1. D’abord, la seule question qui décide

Avant tout attribut : cette icône apporte-t-elle une information que le texte voisin ne donne pas ?

Trois réponses, trois traitements, et rien entre les deux :

L’icône…Ce qu’elle estCe qu’on écrit
double un texte visibledécorativearia-hidden="true"
est le seul contenu d’un bouton ou d’un lienl’intitulé de ce bouton, de ce lienle nom sur le bouton, l’icône masquée
porte seule une informationune imagerole="img" + une alternative

Se tromper de case coûte plus cher qu’oublier un attribut : une icône décorative traitée en image ajoute du bruit à chaque ligne, une image traitée en décoration efface une information.

2. L’icône décorative : la masquer, entièrement

<button type="button">
	<svg viewBox="0 0 20 20" width="16" height="16" aria-hidden="true" focusable="false">
		<path d="M4 10.5l4 4 8-9" fill="none" stroke="currentColor" stroke-width="2" />
	</svg>
	Enregistrer
</button>

aria-hidden="true" retire le SVG de l’arbre d’accessibilité. Le test 1.2.4 va plus loin : il demande aussi que le <svg> et ses enfants soient dépourvus d’alternative, que les balises <title> et <desc> soient absentes ou vides, et qu’aucun attribut title ne traîne. Un seul de ces restes suffit à faire réapparaître l’icône, ou à la faire annoncer deux fois.

focusable="false" demande une explication honnête. Internet Explorer et l’ancien Edge plaçaient chaque <svg> en ligne dans l’ordre de tabulation : sans cet attribut, une barre d’outils de six icônes coûtait six arrêts pour rien. Ces navigateurs ont disparu, et les moteurs actuels ne le font plus. Le RGAA ne l’exige nulle part : c’est une précaution sans coût, pas une règle.

Une note technique du critère 1.2 vise un cas qu’on oublie : quand l’icône est affichée par un <use href="…">, le test s’applique aussi au <svg> référencé — celui du sprite, souvent écrit une fois pour toutes et jamais relu.

3. L’icône seule dans un bouton : nommer le bouton

<button type="button" aria-label="Fermer la notification">
	<svg viewBox="0 0 20 20" width="16" height="16" aria-hidden="true" focusable="false">
		<path d="M5 5l10 10M15 5L5 15" fill="none" stroke="currentColor" stroke-width="2" />
	</svg>
</button>

Le nom se pose sur l’élément interactif, et l’icône est masquée. Deux façons de le faire, également valables :

<!-- aria-label : le nom ne se voit pas -->
<button type="button" aria-label="Fermer la notification"></button>

<!-- texte masqué visuellement : le nom est dans le DOM, traduit, sélectionnable -->
<button type="button">
	<svg aria-hidden="true" focusable="false"></svg>
	<span class="sr-only">Fermer la notification</span>
</button>

Le texte masqué a un avantage discret : il est traduit par les traducteurs automatiques de page, ce que aria-label n’est pas toujours. Choisissez l’un des deux, jamais les deux — aria-label l’emporterait, et l’autre deviendrait un doublon invisible que personne ne relira.

Le nom dit la fonction, pas le dessin : « Fermer la notification », pas « croix ». C’est le critère 1.3, et c’est aussi ce qui rend le bouton utilisable au pilotage vocal : on prononce ce qu’on veut faire.

4. Quand l’icône accompagne un texte : ne rien nommer du tout

<a href="/rapports/2026.pdf">
	<svg aria-hidden="true" focusable="false"></svg>
	Rapport annuel 2026
</a>

C’est le cas le plus fréquent, et celui où l’on ajoute le plus d’attributs inutiles. Le lien a déjà un nom : celui de son texte. Toute alternative posée sur l’icône s’y ajouterait — « Rapport annuel 2026, document » — sans rien apprendre.

5. Le SVG informatif autonome : role="img" et une alternative

<svg viewBox="0 0 20 20" width="22" height="22" role="img" aria-label="Non conforme" focusable="false">
	<circle cx="10" cy="10" r="8" fill="none" stroke="currentColor" stroke-width="1.5" />
	<path d="M7 7l6 6M13 7l-6 6" fill="none" stroke="currentColor" stroke-width="2" />
</svg>

Le test 1.1.5 demande les deux ensemble : role="img" sur la balise <svg>, et une alternative textuelle. Le rôle fait deux choses — il annonce l’élément comme une image, et il aplatit son contenu, de sorte que les <text>, <title> et autres fragments internes ne soient pas lus un à un.

L’alternative peut venir de trois sources, que le test 1.3.6 juge sur leur pertinence : un aria-label, un aria-labelledby vers un passage de texte, ou un élément <title> enfant direct du <svg>. Le <title> a le charme de rester dans le fichier SVG lui-même ; il produit aussi une infobulle au survol, ce qui n’est pas toujours voulu.

Un dernier point, propre à ce cas : une icône de statut porte souvent une information aussi donnée par la couleur. La forme doit alors différer d’un statut à l’autre — croix, coche, tiret — et pas seulement la teinte. La démo le fait ; c’est le critère 3.1 qui l’impose, et non les critères d’images.

6. Avez-vous besoin d’un SVG en ligne ?

<img src="/icones/rapport.svg" alt="" />

Un SVG appelé par <img> redevient une image ordinaire : alt="" s’il décore, alt="…" s’il informe, et le fichier se met en cache. Le SVG en ligne ne se justifie que si vous avez besoin d’en changer les couleurs par currentColor, de l’animer, ou d’en styler des parties. Sinon, <img> demande un attribut là où l’autre en demande trois.

Au clavier

Une icône n’est pas un composant interactif : ce qui prend le focus, c’est le bouton ou le lien qui la porte.

ToucheEffet
TabVa au bouton ou au lien qui contient l’icône. Le <svg> lui-même n’est jamais un arrêt.
Entrée / EspaceActive ce bouton — l’icône n’y est pour rien.
G (NVDA, JAWS)Saute d’image en image : seuls y figurent les SVG exposés comme telles.

Une icône décorative correctement masquée est absente de cette dernière navigation. C’est le contrôle le plus rapide : parcourir les images d’une page et n’y trouver que celles qui disent quelque chose.

Ce que le lecteur d’écran restitue

Sur le bouton à icône seule : « Fermer la notification, bouton ». Sur l’icône de statut : « Non conforme, image ». Sur l’icône décorative : rien, et c’est le résultat attendu. La formulation varie d’un lecteur à l’autre, jamais les informations.

Le diagnostic inverse tient en trois écoutes :

  • Vous n’entendez que « bouton » : le bouton n’a aucun nom accessible.
  • Vous entendez un mot de dessin collé à l’intitulé — « disquette Enregistrer » : l’icône décorative a gardé un <title> ou un aria-label.
  • Vous n’entendez rien là où une information est affichée : le SVG informatif n’a ni role="img" ni alternative, et l’information n’existe que pour l’œil.

Checklist

  • Trancher d’abord : décorative, intitulé d’un contrôle, ou image ?
  • Icône décorative : aria-hidden="true", sans <title>, <desc> ni title.
  • Icône seule dans un bouton : le nom sur le bouton, l’icône masquée.
  • Nommer la fonction, jamais le dessin.
  • SVG informatif : role="img" et une alternative, les deux.
  • Icône de statut : une forme différente, pas seulement une couleur.
  • Vérifier les sprites <use> : le SVG référencé compte aussi.

Les critères RGAA en jeu

Vérifiez votre composant avec l'extension

Pour aller plus loin

Sources