Chapitre 5.5 — Contenu masqué (sr-only)
⏱️ TL;DR — « Masquer » n’est pas une action unique : il y a quatre façons de le faire, et elles n’ont pas le même effet sur l’arbre d’accessibilité.
display:none(ou l’attributhidden) cache pour tout le monde. La classesr-only(aussi ditevisually-hidden) masque à l’œil mais laisse lire par le lecteur d’écran — parfait pour un texte d’aide invisible.aria-hidden="true"fait l’inverse : visible à l’œil, retiré de l’arbre — pour le décoratif. Enfin, le texte de remplacement (alt, texte accessible) remplace un visuel muet. Choisir la bonne technique, c’est décider qui perçoit quoi.
🎯 Objectifs
- Distinguer les quatre techniques de masquage et leur effet sur l’arbre.
- Écrire la classe
sr-only/visually-hiddencorrecte (CSS complet). - Utiliser
aria-hidden="true"pour le décoratif, sans casser l’accessibilité. - Lire le tableau croisé « visible à l’œil ? / lu par le lecteur ? ».
- Éviter le piège d’
aria-hiddensur un élément focusable.
Quatre façons de masquer
1. display:none / l’attribut hidden — masqué pour tout le monde
Ces deux techniques retirent l’élément du rendu ET de l’arbre d’accessibilité. Personne ne le voit, personne ne l’entend. C’est le masquage « total », pour du contenu réellement inactif (un panneau replié, une étape non atteinte).
<!-- Absent de l'écran ET de l'arbre : ni vu, ni lu -->
<div hidden>Contenu pas encore actif</div>
<div style="display:none">Idem</div>visibility:hidden a le même effet d’exclusion de l’arbre, mais réserve la place dans la mise en page.
2. La classe sr-only / visually-hidden — invisible à l’œil, LUE par le lecteur
C’est la technique la plus utile de ce chapitre. Elle rend le contenu invisible visuellement tout en le gardant dans l’arbre, donc lu par le lecteur d’écran. On l’utilise pour donner un contexte que le visuel porte déjà autrement (par la position, une icône, la couleur).
Attention : ne l’improvise pas. display:none ou visibility:hidden retireraient le texte de l’arbre — l’inverse du but. La recette éprouvée réduit l’élément à un pixel « écrasé » sans le retirer :
.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;
}<!-- "Résultats de recherche" est lu, mais n'encombre pas le design -->
<h2 class="sr-only">Résultats de recherche</h2>
<!-- Le lien affiche une flèche ; le lecteur, lui, entend la destination -->
<a href="/panier">
<span aria-hidden="true">🛒</span>
<span class="sr-only">Voir mon panier</span>
</a>♿ Côté utilisateur — Le texte
sr-onlyest un cadeau discret. Là où l’œil comprend par le contexte visuel (« ce champ de recherche, cette icône loupe »), l’oreille a besoin de mots. Un « Rechercher sur A11yLearn » invisible mais lu transforme un champ énigmatique en champ clairement nommé — sans rien changer au design pour les personnes voyantes.
3. aria-hidden="true" — visible à l’œil, RETIRÉ de l’arbre
L’inverse exact de sr-only. L’élément reste affiché mais disparaît de l’arbre (lui et ses descendants). C’est fait pour le décoratif : icônes purement ornementales, doublons d’information, éléments visuels sans valeur ajoutée à l’oreille.
<!-- L'icône est décorative : on la retire de l'arbre, le texte suffit -->
<button>
<span aria-hidden="true">✕</span>
Fermer
</button>
<!-- Doublon : la même info est déjà lue ailleurs, on évite de la répéter -->
<span aria-hidden="true">→</span>Sans aria-hidden, une icône ✕ pourrait s’annoncer « croix de Saint-André » ou « caractère multiplication » — du bruit inutile en plus du mot « Fermer ».
4. Le texte de remplacement — donner des mots à un visuel
Quand l’information est portée par un visuel (image, icône signifiante, graphique), on ne masque pas : on fournit une alternative textuelle lue à la place. L’alt d’une image en est l’exemple canonique ; un aria-label sur un bouton-icône joue le même rôle.
<!-- L'image porte du sens : alt descriptif (lu à la place du pixel) -->
<img src="badge-termine.svg" alt="Cours terminé">
<!-- Icône signifiante seule dans un bouton : aria-label fournit le nom -->
<button aria-label="Ajouter aux favoris">
<svg aria-hidden="true"> ... </svg>
</button>Note le combo fréquent : l’aria-label nomme le bouton, et le <svg> décoratif à l’intérieur est masqué par aria-hidden="true" pour ne pas parasiter. Une image décorative, elle, prend un alt="" (vide) pour être ignorée du lecteur.
Tableau croisé
| Technique | Visible à l’écran ? | Lu par le lecteur d’écran ? | Quand l’utiliser |
|---|---|---|---|
display:none / hidden | Non | Non | Contenu inactif, à cacher pour tous |
visibility:hidden | Non (place réservée) | Non | Idem, en gardant l’espace |
.sr-only / visually-hidden | Non | Oui | Texte de contexte pour le lecteur seul |
aria-hidden="true" | Oui | Non | Décoratif, doublon, icône ornementale |
Texte de remplacement (alt, aria-label) | Le visuel reste | Oui (l’alternative) | Visuel porteur de sens |
Retiens les deux cases « opposées » : sr-only = caché à l’œil, ouvert à l’oreille ; aria-hidden = ouvert à l’œil, caché à l’oreille. Presque tous les besoins réels se ramènent à choisir entre ces deux-là (plus display:none quand il faut tout cacher).
⚠️ Piège — Ne mets jamais
aria-hidden="true"sur un élément focusable (un<a href>, un<button>, un champ), ni sur un conteneur qui en contient. L’élément disparaît de l’arbre… mais reste atteignable au clavier (Tab). Résultat : l’utilisateur de lecteur d’écran arrive dessus au focus, et le lecteur n’a rien à annoncer — un « trou noir » déroutant. Si tu veux retirer un contrôle de l’expérience, retire-le du flux (display:none) ou du parcours clavier, pas seulement de l’arbre.
<!-- ❌ Focusable mais invisible pour le lecteur : silence au focus -->
<button aria-hidden="true">Valider</button>
<!-- ✅ Vraiment inactif : hors rendu, hors arbre, hors clavier -->
<button hidden>Valider</button>🧭 Sur A11yLearn — Deux correctifs typiques sur A11yLearn. (1) Le champ de recherche du header n’avait qu’une icône loupe — muet à l’oreille. On a ajouté un
<label class="sr-only">Rechercher un cours</label>: invisible, mais le champ s’annonce enfin. (2) Les cartes de cours affichaient une coche décorative✔en plus du texte « Terminé » ; le lecteur lisait « coche Terminé », redondant. On a misaria-hidden="true"sur la coche : l’œil garde le picto, l’oreille n’entend que « Terminé ». Même écran, deux publics, chacun servi juste.
✏️ Exercices
Exercice 1 — Choisis la technique. Pour chaque besoin, dis quelle technique employer : (a) une flèche → purement décorative dans un lien, (b) préciser « (ouvre un nouvel onglet) » pour le lecteur sans surcharger le design, (c) un panneau d’accordéon actuellement replié.
✅ Solution
(a) aria-hidden="true" sur la flèche : elle reste visible mais n’est plus lue (décorative). (b) sr-only : un <span class="sr-only">(ouvre un nouvel onglet)</span> invisible mais lu, pour prévenir sans alourdir l’écran. (c) display:none ou l’attribut hidden sur le panneau replié : inactif, il doit disparaître pour tous — et réapparaître (retour dans l’arbre) à l’ouverture. Chacun cible une case différente du tableau croisé.
Exercice 2 — Répare le bouton-icône. Corrige ce code pour qu’il soit correctement annoncé, sans bruit parasite : <button><svg><!-- icône corbeille --></svg></button>.
✅ Solution
Le bouton n’a aucun nom accessible (il ne contient qu’un <svg>), et le <svg> pourrait générer du bruit. On nomme le bouton et on masque l’icône :
<button aria-label="Supprimer">
<svg aria-hidden="true"><!-- icône corbeille --></svg>
</button>Résultat annoncé : « Supprimer, bouton ». L’aria-label fournit le nom (chapitre 5.3), aria-hidden="true" retire l’icône décorative de l’arbre. Vérifie dans le panneau Accessibility que le nom n’est plus vide.
🧠 Quiz de révision
1. Quelle est la différence d’effet entre sr-only et aria-hidden="true" ?
sr-only et aria-hidden="true" ?Ils sont opposés. .sr-only (visually-hidden) masque l’élément à l’œil mais le garde dans l’arbre (lu par le lecteur). aria-hidden="true" laisse l’élément visible à l’œil mais le retire de l’arbre (non lu). L’un pour un texte réservé au lecteur, l’autre pour du décoratif.
2. Pourquoi ne pas utiliser display:none pour un texte destiné au lecteur d’écran ?
display:none pour un texte destiné au lecteur d’écran ?Parce que display:none (comme visibility:hidden) retire l’élément de l’arbre d’accessibilité : il ne serait pas lu. Pour un texte invisible mais lu, il faut la classe .sr-only, qui écrase l’élément à un pixel sans le retirer de l’arbre.
3. Écris (de mémoire, à peu près) l’idée de la classe .sr-only.
.sr-only.position:absolute, width:1px/height:1px, overflow:hidden, clip:rect(0,0,0,0), margin:-1px, white-space:nowrap, border:0. On réduit l’élément à un point invisible sans display:none, pour qu’il reste dans l’arbre et soit lu.
4. Quand utiliser un texte de remplacement (alt, aria-label) plutôt qu’un masquage ?
alt, aria-label) plutôt qu’un masquage ?Quand le visuel porte du sens : une image informative, un bouton-icône, un graphique. On ne cache pas l’info, on la traduit en texte lu à la place (alt d’image, aria-label de contrôle). Une image purement décorative prend un alt="" vide pour être ignorée.
5. Pourquoi aria-hidden="true" sur un <button> est-il dangereux ?
aria-hidden="true" sur un <button> est-il dangereux ?Parce que le bouton reste focusable au clavier (Tab) tout en étant absent de l’arbre : l’utilisateur de lecteur d’écran y arrive au focus, mais rien n’est annoncé — un « trou » silencieux et déroutant. Pour désactiver vraiment un contrôle, retire-le du flux (hidden/display:none) et du parcours clavier, pas seulement de l’arbre.
Partie suivante : Partie 6 — WAI-ARIA en profondeur — quand le HTML natif ne suffit plus, comment enrichir rôles, noms et états avec ARIA, sans casser ce que l’arbre te donnait déjà.