Le 29 mars dernier, l’organisation américaine WebAIM a publié son rapport 2023 sur l’état de l’accessibilité du web. Parmi toutes les erreurs détectées, la très grande majorité sont des problèmes de design et / ou de HTML faciles à corriger.
Depuis 2019, l’organisation à but non lucratif WebAIM publie chaque année les résultats d’une analyse effectuée sur un million de pages d’accueil appartenant aux sites les plus consultés du web. Parmi ce million de sites, on retrouve évidemment les gros noms d’Internet tels que Facebook, Google, Youtube, Amazon ou Wikipedia, ainsi que des sites gouvernementaux, de technologies, d’écoles, des boutiques en ligne, etc.
Le rapport The WebAIM Million de 2023 a été publié le 29 mars, et montre que même si l’accessibilité du web progresse un peu, beaucoup de travail reste à faire.
Parmi toutes les erreurs détectées au cours des tests effectués par WebAIM, 96% entrent dans une des six catégories suivantes:
- Texte avec un contraste de couleur insuffisant: 83.6% des pages testées;
- Texte alternatif des images manquant ou inadéquat: 58.2% des pages testées;
- Liens sans intitulé: 50.1% des pages testées;
- Champs de formulaires sans étiquette: 45.9% des pages testées;
- Boutons sans intitulé: 27.5% des pages testées;
- Langue du document manquante: 18.6% des pages testées.
La bonne nouvelle, c’est qu’elles sont toutes faciles à corriger et à éviter. La mauvaise, c’est que malgré ça, les plus gros sites continuent de faire ces erreurs, année après année.
Dans ce billet, je vous explique pour chacune d’entre elles ce qui pose problème exactement, et surtout comment les corriger pour rendre votre site accessible au plus grand nombre d’internautes possible.
Les référentiels mentionnés sont les Web Content Accessibility Guidelines (WCAG) éditées par le World Wide Web Consortium, et le Référentiel Général d’Accessibilité Numérique (RGAA) du gouvernement français.
Texte avec un contraste de couleur insuffisant
Il s’agit de l’erreur d’accessibilité détectée le plus fréquemment dans le cadre de tests automatiques: même Facebook (le #1 du million de sites inclus dans l’échantillon de WebAIM) échoue, à cause du bleu des liens. Pas bravo Facebook. La situation a d’ailleurs très peu évolué depuis 2019, le pourcentage de pages avec des textes qui présentaient un contraste insuffisant était alors de 85.3%.
Pourquoi c’est important ? Si la couleur d’un texte est trop proche de celle de l’arrière-plan, les internautes qui ont certains handicaps visuels risquent d’avoir des difficultés à le lire. D’une manière générale, plus le contraste entre la couleur du texte et celle de l’arrière-plan est faible, moins le texte sera confortable à lire et moins il sera accessible.
Pour éviter ça, les WCAG définissent des rapports de contraste minimums:
- 4.5:1 pour tous les textes dont la taille est inférieure ou égale à 18px (14pt);
- 4.5:1 pour les textes en graisse normale dont la taille est inférieure à 24px (18pt);
- 3:1 pour les textes en gras dont la taille est supérieure à 18px (14pt);
- 3:1 pour tous les textes dont la taille est supérieure à 24px (18pt).
Comment on corrige ? Il revient à la fois aux designers de s’assurer que les couleurs qu’ils et elles combinent dans leurs maquettes présentent un contraste suffisant, et aux développeur·euses de signaler et corriger le problème au moment d’implémenter le design.
De nombreux outils permettent de vérifier le rapport de contraste, et de le corriger si nécessaire. Voici ceux que j’utilise personnellement:
- Des outils en ligne tels que Contrast Ratio ou le Color Contrast Checker de Coolors permettent la vérification manuelle du rapport de contraste entre deux couleurs.
- Colour Contrast Analyser, une petite application disponible pour Windows et MacOS, qui permet également de vérifier le contraste entre deux couleurs.
- Accessible Colors qui permet de préciser la taille et la graisse du texte, et propose des alternatives lorsque le contraste de base n’est pas suffisant.
- Accessible color palette, un outil hyper pratique qui permet d’entrer jusqu’à six couleurs et de voir lesquelles peuvent être combinées.
Pour les designers, il existe des extensions qu’on peut installer directement dans nos applications de design préférées, par exemple:
- Stark (Figma, Adobe XD, Sketch)
- UseContrast et Contrast (uniquement pour Figma, que je n’ai pas testées)
Pour les devs, des outils plus techniques permettent de vérifier les rapports de contrastes directement depuis le navigateur, ou de détecter automatiquement les problèmes de contraste d’une page web:
- Dans Firefox et Chrome, l’inspecteur de styles natif inclut un outil de vérification du contraste.
- Plusieurs extensions de navigateur permettent d’effectuer des tests d’accessibilité automatiques, qui détectent les éventuels problèmes de contraste: axe DevTools (Firefox et Chrome), Lighthouse (native dans Chrome, disponible également pour Firefox) ou WAVE (Chrome, Firefox, Edge).
Les personnes qui entrent le contenu d’un site doivent également être attentives aux questions de lisibilité lorsqu’elles ont la possibilité de choisir la couleur de l’arrière plan ou du texte d’un module. Si vous utilisez l’éditeur natif de WordPress, un avertissement s’affiche si vous sélectionnez une combinaison de couleurs dont le contraste n’est pas suffisant.
Liens et ressources
- Référentiels: critère 3.2 du RGAA 4 et 1.4.3 des WCAG 2.1
- Accessibilité et couleurs: outils et ressources pour concevoir des produits accessibles par Stéphanie Walter
- Orange You Accessible? A Mini Case Study on Color Ratio par Ericka O’Connor (en anglais)
Texte alternatif des images manquant ou inadéquat
Le texte alternatif permet de décrire une image dans le cas où elle ne peut pas être affichée. En HTML, il se trouve dans l’attribut alt
de la balise <img>
.
Pour 22% des images présentes sur les pages testées par WebAIM, le texte alternatif était totalement absent; 11% des images avaient un texte alternatif peu pertinent (par exemple juste ‘image’), ou redondant par rapport au contenu qui se trouvait à proximité de l’image.
Pourquoi c’est important ? Le texte alternatif sert principalement aux lecteurs d’écran (logiciels de synthèse vocale ou plages braille) utilisés par les personnes aveugles ou malvoyantes: si l’attribut alt
contient du texte, celui-ci est lu par le logiciel; s’il est vide, l’image est ignorée.
Lorsque l’attribut alt
est totalement absent, le lecteur d’écran énonce en général le nom du fichier de l’image. Si l’image a été nommée de manière explicite, par exemple ‘panda-roux.jpg’, au moins l’utilisateur a une idée de ce qu’elle représente (même si c’est pas terrible). En revanche, si le nom de l’image est ‘IMG_2314.jpg’ ou ‘Capture-d-ecran-2023-04-17-a-15.22.38.png’… bon, c’est pire que pas terrible.
Comment on corrige ? Dans tous les cas, l’attribut alt
DOIT être présent sur l’image, même s’il reste vide.
Lorsqu’une image comporte des informations nécessaires à la bonne compréhension du contenu, le texte alternatif doit contenir toutes les informations qui manquent si on ne peut pas voir l’image.
Dans l’exemple ci-dessous, la date et le lieu du festival figurent sur l’image de l’affiche mais ne sont pas indiqués dans le texte. On ajoute donc ces informations dans l’attribut alt
de l’image:
<img src="affiche-plusqile-festival.jpg" alt="plusQ'île festival, du 7 au 11 juin 2023 à Bienne">
<p>Nous nous réjouissons de vous rencontrer lors de la prochaine édition du plusQ'île festival !</p>
Le texte qui figure dans l’attribut alt
doit être utile et pertinent. Ça n’a par exemple aucun intérêt d’utiliser la même description sur toutes les images d’une page; au contaire, ça ralentit inutilement la lecture du contenu. On évitera aussi de juste indiquer ‘image’, ‘graphique’, le nom du fichier ou une liste de mots clés pensés pour le SEO.
Le texte alternatif est également utile pour les images qui complètent le contenu textuel, qui servent à apporter du contexte ou à véhiculer une émotion particulière.
En revanche, dans le cas où une image est purement décorative, ou que les informations qu’elle contient sont également présentes dans le texte à proximité, on laisse l’attribut alt
vide.
<img src="affiche-plusqile-festival.jpg" alt="">
<p>Le plusQ'île festival est un festival de cirque dont la prochaine édition aura lieu du 7 au 11 juin 2023 à Bienne. Nous nous réjouissons de vous y rencontrer !</p>
Liens et ressources
- Référentiels: critères 1.1 à 1.3 du RGAA 4 et 1.1.1 des WCAG 2.1
- Utiliser les images de manière accessible
Liens et boutons sans intitulé
Un lien ou un bouton est considéré comme vide lorsqu’il ne contient aucun texte.
On rencontre principalement des liens vides lorsqu’ils contiennent uniquement une image, dont l’attribut alt
n’est pas renseigné. Je remarque par exemple souvent ce problème dans les liens sous forme d’icônes qui amènent vers des pages de réseaux sociaux.
Cette erreur est également souvent présente lorsque un bouton contient uniquement une icône, par exemple le bouton hamburger qui permet d’afficher le menu mobile, ou les flèches de défilement d’un slideshow.
Pourquoi c’est important ? Les internautes devraient toujours pouvoir anticiper ce qu’il va se passer s’ils ou elles cliquent sur un élément interactif. Or, si un lien ou un bouton ne contient pas de texte, un lecteur d’écran ne sera pas en mesure d’indiquer clairement à la personne qui l’utilise qu’il s’agit d’un lien vers une page Facebook, ou qu’elle s’apprête à afficher le menu.
Dans le cas d’un lien avec une image sans texte, les lecteurs d’écran annoncent bien qu’il s’agit d’un lien, puis essaient de déduire la cible d’après la dernière partie de l’URL ou le nom du fichier. La restitution diffère selon les logiciels et les navigateurs, Manuel Matuzović a consacré un billet de blog entier à ce sujet.
L’exemple ci-dessous sera par exemple restitué de la manière suivante par VoiceOver sur MacOS: « lien, image, alinekeller.ch ». L’internaute n’a donc aucune idée de la cible réelle du lien – dans ce cas précis, il ou elle est même induit·e en erreur puisque la restitution par VoiceOver laisse penser que le lien mène à mon site web, et pas à mon compte Instagram.
<a href="https://instagram.com/alinekeller.ch">
<img src="icon-instagram.png" alt="">
</a>
Comment on corrige ? Les liens comme les boutons doivent avoir un nom accessible, c’est à dire un texte qui indique de manière claire la cible du lien, ou l’action que le clic sur le bouton va déclencher.
Si on ne souhaite pas que ce texte soit visible à l’écran, on peut le cacher à l’aide d’une technique de masquage accessible – par exemple une classe .screen-reader-only
, .visually-hidden
, etc.
<a href="…">
<img src="icon-instagram.png" alt="">
<span class="sr-only">Instagram</span>
</a>
J’utilise pour ma part la méthode proposée par Scott O’Hara pour cacher du contenu de manière inclusive. Attention à ne pas utiliser display:none
pour masquer le texte, puisqu’il serait alors également caché pour les lecteurs d’écran.
.sr-only:not(:focus):not(:active) {
clip: rect(0 0 0 0);
clip-path: inset(50%);
height: 1px;
overflow: hidden;
position: absolute;
white-space: nowrap;
width: 1px;
}
Lorsque le lien contient une image, le nom accessible peut aussi être indiqué dans l’attribut alt
:
<a href="…">
<img src="icon-instagram.png" alt="Instagram">
</a>
J’ai une préférence personnelle pour la première méthode, mais du point de vue de l’accessibilité, les deux sont valides et restituées de manière identique: « lien, Instagram ».
Pour les boutons, on procède de la même façon: même si le texte est masqué, comme par exemple pour un bouton hamburger, il doit tout de même être présent dans le code de la page pour les lecteurs d’écran. Les trois exemples ci-dessous seront restitués correctement et permettront aux internautes d’utiliser le bouton:
<button class="toggle-menu">
<svg aria-hidden="true">[contenu SVG]</svg>
<span class="sr-only">Afficher le menu</span>
</button>
<button class="toggle-menu">
<img src="icon-burger.svg" alt="">
<span class="sr-only">Afficher le menu</span>
</button>
<button class="toggle-menu">
<img src="icon-burger.svg" alt="Afficher le menu">
</button>
Liens et ressources
- Référentiels: critères 6 (liens) et 11.9 (boutons) du RGAA 4 et 1.1.1, 2.4.4, 2.5.3 et 4.1.2 des WCAG 2.1
- Les noms accessibles dans tous leurs états par Lena Chandelier (24 jours de web)
- 50.1% empty links par Manuel Matuzović (en anglais)
- Accessible Text Labels For All par Sara Soueidan (en anglais)
Champs de formulaire sans étiquette
Lorsqu’on remplit un formulaire, l’étiquette permet de savoir quelle information est attendue dans le champ correspondant. Elle est en général placée au-dessus ou juste à côté du champ, de manière à y être associée visuellement. Ce lien doit également exister dans le code, afin que les logiciels de lecture d’écran ou de commande vocale puissent identifier quel champ correspond à quelle étiquette.
Pourquoi c’est important ? Lorsqu’un champ de formulaire n’a pas d’étiquette indiquée dans le code, les personnes qui utilisent un lecteur d’écran ou un logiciel de commande vocale rencontreront des difficultés pour remplir le formulaire, voire n’y parviendront pas du tout.
Dans l’exemple ci-dessous, l’étiquette « Prénom » n’est pas liée au champ de texte, qui n’est donc pas utilisable correctement:
<p class="label">Prénom</p>
<input type="text">
Même problème pour ce formulaire de recherche: visuellement, on comprend de quoi il s’agit grâce au placeholder et à l’icône de loupe, mais un utilisateur aveugle ne pourra pas savoir à quoi correspondent ce champ et ce bouton.
<form>
<input type="search" placeholder="Recherche">
<input type="image" src="icon-loupe.png">
</form>
Comment on corrige ? Plusieurs méthodes permettent de lier une étiquette à un champ de formulaire. La plus simple consiste à associer l’élément <label>
au champ qui lui correspond. On utilise pour cela l’attribut for
, dont la valeur doit correspondre à l’id de l’élément <input>
, <select>
, <textarea>
, … qu’on souhaite lier au <label>
. Par exemple:
<label for="form-firstname">Prénom</label>
<input type="text" id="form-firstname">
Autre avantage de cette méthode: lorsqu’on clique sur l’étiquette, le curseur est automatiquement placé dans le champ correspondant. Ci-dessous, trois champs de formulaire et leurs étiquettes, associés visuellement et dans le code au moyen du <label>
:
Il est en général préférable que l’étiquette de chaque champ reste toujours visible, y compris lorsque le champ prend le focus ou qu’on y a saisi du contenu. C’est particulièrement important pour les formulaires qui comprennent plusieurs champs, et peuvent être complexes à remplir.
Dans le cas de formulaires simples, où il n’y a pas de risque de confusion entre plusieurs champs (par exemple un formulaire de recherche basique), on peut se contenter de définir l’étiquette au moyen de l’attribut aria-label
. Elle ne sera alors pas visible à l’écran, mais bien présente pour les technologies d’assistance qui en ont besoin.
<form>
<input type="search" aria-label="Champ de recherche" placeholder="Entrez un mot clé">
<input type="submit" aria-label="Rechercher">
</form>
L’attribut placeholder
ne doit en revanche jamais être utilisé seul en guise d’étiquette. Bien que cette pratique soit considérée comme valide par les outils de tests d’accessibilité, elle peut rendre un formulaire compliqué à remplir pour une personne avec un trouble de l’attention, des problèmes de mémoire, ou d’autres difficultés cognitives.
Liens et ressources
- Référentiels: critères 8.3 et 8.4 du RGAA 4 et 3.1.2 des WCAG 2.1
- Le placeholder n’est pas un label ! par Romy Duhem-Verdière
- Placeholder et accessibilité par Johan Ramon (Atalan)
Langue du document manquante
Pourquoi c’est important ? Il est indispensable de préciser la langue principale de chaque page d’un site, afin que les lecteurs d’écran sachent comment restituer le contenu. Si la langue principale de la page n’est pas définie, ou mal définie, la langue de restitution ne sera peut-être pas la bonne et le contenu sera incompréhensible pour l’utilisateur.
Comment on corrige ? L’attribut lang
doit être spécifié dans la balise <html>
de chaque page. Sa valeur doit être un code de langue ISO valide. Il s’agit en général d’un code de deux lettres (par exemple ‘fr’ pour le français, ‘en’ pour l’anglais, ‘de’ pour l’allemand), mais on peut également l’indiquer sous la forme ‘fr-CH’ pour préciser qu’il s’agit de français suisse ou ‘en-GB’ pour de l’anglais britannique.
<html lang="fr">
Liens et ressources
- Référentiels: critères 11.1 à 11.4 du RGAA 4 et 3.1.2 des WCAG 2.1