CSS visually-hidden : masquer visuellement sans perdre l'accessibilité
En Bref : L'essentiel à retenir
- La classe visually-hidden masque le contenu visuellement tout en le gardant accessible aux lecteurs d'écran, contrairement à display:none qui le supprime.
- La technique moderne utilise clip-path inset(50%) au lieu de l'ancien clip qui est déprécié, avec position absolute et dimensions de 1px.
- Les éléments focusables masqués doivent redevenir visibles au focus avec la variante :not(:focus):not(:active) pour les liens d'évitement.
- Préférez visually-hidden à aria-label pour les textes qui doivent être traduits automatiquement et rester maintenables.
Comment ajouter du contexte pour les lecteurs d'écran sans encombrer l'interface visuelle ? La technique visually-hidden (aussi appelée sr-only) est la réponse. Mais attention : mal implémentée, elle peut créer plus de problèmes qu'elle n'en résout.
Le problème : masquer sans supprimer
En CSS, cacher un élément semble simple. Mais chaque méthode a des conséquences différentes :
| Technique | Visible | Accessible | Focusable |
|---|---|---|---|
display: none | Non | Non | Non |
visibility: hidden | Non | Non | Non |
opacity: 0 | Non | Oui | Oui |
visually-hidden | Non | Oui | Non* |
display: none et visibility: hidden retirent complètement l'élément de l'arbre d'accessibilité. Les lecteurs d'écran ne peuvent pas y accéder.
[!NOTE] Le critère RGAA 10.2 stipule que le contenu visible doit rester compréhensible quand les feuilles de style sont désactivées. Le texte masqué avec visually-hidden apparaîtra alors.
La classe visually-hidden moderne
Voici l'implémentation recommandée en 2026 :
.visually-hidden {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip-path: inset(50%);
white-space: nowrap;
border: 0;
}
Décortiquons chaque propriété
position: absolute: retire l'élément du flux sans affecter la mise en pagewidth/height: 1px: réduit à la taille minimalemargin: -1px: compense le pixel restantoverflow: hidden: empêche tout débordementclip-path: inset(50%): masque l'élément (remplace l'ancienclip)white-space: nowrap: évite que le texte crée une zone de scroll
[!TIP] L'ancienne propriété
clip: rect(0, 0, 0, 0)est dépréciée. Utilisezclip-path: inset(50%)pour une meilleure compatibilité future.
Éléments focusables : la variante importante
Un lien d'évitement (skip link) doit apparaître quand il reçoit le focus. Sans cette variante, l'utilisateur clavier ne voit pas où est son focus.
.visually-hidden:not(:focus):not(:active) {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip-path: inset(50%);
white-space: nowrap;
border: 0;
}
Avec cette règle, l'élément devient visible dès qu'il reçoit le focus :
<a href="#main-content" class="visually-hidden">
Aller au contenu principal
</a>
Consultez notre guide sur les liens d'évitement pour l'implémentation complète.
Cas d'usage courants
1. Liens "Lire la suite" contextualisés
Sans contexte, les lecteurs d'écran lisent "Lire la suite, lien" répété pour chaque article. Ajoutez du contexte invisible :
<a href="/article-123">
Lire la suite
<span class="visually-hidden">de l'article : Accessibilité des formulaires</span>
</a>
Le lecteur d'écran lit : "Lire la suite de l'article : Accessibilité des formulaires, lien".
2. Labels de formulaire invisibles
Quand le design impose un champ sans label visible (comme une barre de recherche avec placeholder) :
<label for="search" class="visually-hidden">Rechercher sur le site</label>
<input type="search" id="search" placeholder="Rechercher...">
<button type="submit">
<svg aria-hidden="true"><!-- icône loupe --></svg>
<span class="visually-hidden">Lancer la recherche</span>
</button>
3. Instructions pour lecteurs d'écran
Ajoutez des instructions que seuls les utilisateurs de technologies d'assistance entendront :
<nav aria-label="Pagination">
<span class="visually-hidden">Vous êtes actuellement sur la page 3 sur 10</span>
<a href="?page=2">Précédent</a>
<a href="?page=4">Suivant</a>
</nav>
4. Tableaux complexes
Clarifiez les relations dans un tableau sans alourdir visuellement :
<table>
<caption>
Comparatif des formules
<span class="visually-hidden">. 3 formules comparées sur 4 critères.</span>
</caption>
<!-- ... -->
</table>
Frameworks et bibliothèques
La plupart des frameworks CSS incluent déjà cette classe :
| Framework | Classe |
|---|---|
| Bootstrap 5 | .visually-hidden |
| Tailwind CSS | .sr-only |
| Foundation | .show-for-sr |
| Bulma | .is-sr-only |
<!-- Tailwind CSS -->
<span class="sr-only">Texte pour lecteurs d'écran</span>
<!-- Bootstrap -->
<span class="visually-hidden">Texte pour lecteurs d'écran</span>
Visually-hidden vs aria-label
Ces deux techniques semblent équivalentes, mais présentent des différences importantes :
| Aspect | visually-hidden | aria-label |
|---|---|---|
| Traduction automatique | Oui | Non |
| Visible sans CSS | Oui | Non |
| Maintenabilité | Dans le HTML | Dans l'attribut |
| Support navigateurs | Universel | Excellent |
Préférez visually-hidden quand :
- Le texte doit être traduit automatiquement
- Vous voulez que le contenu soit visible si CSS échoue
- Le texte est long ou complexe
Préférez aria-label quand :
- Vous labellisez un élément interactif unique
- Le texte est court et simple
- Vous contrôlez les traductions manuellement
L'opposé : masquer aux lecteurs d'écran
Parfois, vous voulez cacher quelque chose aux lecteurs d'écran tout en le montrant visuellement (icône décorative, image répétitive) :
<!-- L'icône est visuelle mais le texte est lu -->
<button>
<svg aria-hidden="true"><!-- icône --></svg>
Envoyer
</button>
L'attribut aria-hidden="true" retire l'élément de l'arbre d'accessibilité.
[!WARNING] N'utilisez jamais
aria-hidden="true"sur un élément focusable ou contenant des éléments focusables. Cela crée une expérience confuse.
Erreurs courantes
1. Utiliser height: 0
/* Problématique dans certains lecteurs d'écran */
.bad-hidden {
height: 0;
overflow: hidden;
}
Certaines technologies d'assistance ignorent les éléments sans hauteur.
2. Oublier white-space: nowrap
Sans cette propriété, un long texte masqué peut créer une zone de scroll invisible perturbant la mise en page.
3. Masquer trop de contenu
Si vous masquez des paragraphes entiers, demandez-vous si ce contenu n'est pas nécessaire pour tous. Le design peut souvent être adapté.
Test de validation
Vérifiez que votre implémentation fonctionne :
- Désactivez CSS dans les DevTools : le texte masqué doit apparaître
- Testez avec un lecteur d'écran : le texte doit être lu
- Naviguez au clavier : les éléments focusables doivent apparaître au focus
Conclusion
La technique visually-hidden est un outil essentiel pour l'accessibilité web. Elle permet d'enrichir l'expérience des utilisateurs de technologies d'assistance sans compromettre le design visuel. Utilisez-la judicieusement pour ajouter du contexte là où il manque.
Vérifiez l'accessibilité de votre contenu masqué avec RGAA Checker : notre outil analyse la structure sémantique et détecte les problèmes de nommage accessible.
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.