Cours HTML et CSS · Module 10: Accessibilité (a11y)

Les tests d'accessibilité

9 min de lecture
Dans cette leçon6

Tu as construit la page du musée en suivant toutes les règles de ce module. Mais comment savoir si elle fonctionne vraiment ? Il est facile de passer à côté d'un alt manquant ou d'un champ sans étiquette, tant que tu ne parcours pas toi-même la page comme le font les autres. Même la meilleure connaissance de l'accessibilité ne remplace pas les tests pratiques. Tout comme les archéologues explorent méthodiquement les sites de fouilles, nous devons tester systématiquement l'accessibilité de nos pages, avec différents outils et différentes méthodes.

Les tests vont du plus rapide au plus exigeant : d'abord un outil automatique (Lighthouse ou axe), puis un test au clavier, ensuite un lecteur d'écran et, pour finir, des tests avec des utilisateurs en situation de handicap. Chaque étape détecte des erreurs que la précédente ne voit pas.

Les outils automatiques

Lighthouse (intégré aux Chrome DevTools)

Lighthouse est un outil gratuit de Google que tu peux lancer directement depuis les Chrome DevTools :

  1. Ouvre les DevTools (F12)
  2. Va dans l'onglet « Lighthouse »
  3. Coche « Accessibility »
  4. Clique sur « Analyze page load »

Lighthouse vérifie notamment :

  • Si les images ont un texte alternatif
  • Si le contraste des couleurs est suffisant
  • Si les éléments de formulaire ont des étiquettes
  • Si la page a une hiérarchie de titres correcte

Attention : un score de 100 ne signifie pas que la page est entièrement accessible. L'outil vérifie si une image a un alt, mais il ne peut pas juger si cet alt a du sens - c'est pourquoi les tests manuels viennent toujours ensuite.

axe DevTools

axe est l'un des outils de test d'accessibilité les plus populaires - une extension de navigateur basée sur le moteur axe-core, que Lighthouse utilise aussi. Il décrit chaque problème selon un format fixe :

1<!-- Un résultat de test axe pourrait ressembler à ceci : -->
2<!--
3  Violation: Images must have alternate text
4  Element: <img src="pharaoh.jpg">
5  Fix: Add an alt attribute to the image
6  Impact: Critical
7  WCAG: 1.1.1 (Level A)
8-->

Le rapport dit ce qui ne va pas, comment le corriger, quelle est la gravité du problème (Impact) et quel critère WCAG est concerné - ici le 1.1.1, c'est-à-dire les alternatives textuelles.

HTML Validator (W3C)

Un HTML correct est le fondement de l'accessibilité, car les lecteurs d'écran s'appuient sur l'arbre d'éléments construit à partir de ton code. Le validateur détecte les erreurs qui cassent cet arbre :

1<!-- Erreurs détectées par le validateur : -->
2
3<!-- Erreur : Attribut alt manquant -->
4<img src="photo.jpg">
5
6<!-- Erreur : ID en double -->
7<input id="name">
8<label id="name">
9
10<!-- Erreur : Imbrication incorrecte -->
11<p>Texte <div>dans un div</div> dans un paragraphe</p>

Un id en double casse les liaisons for et aria-describedby, et un <div> placé à l'intérieur d'un <p> pousse le navigateur à fermer le paragraphe plus tôt que tu ne le voulais. Tu découvriras le validateur plus en détail dans le prochain module.

Les tests manuels

Le test au clavier

Voici le test manuel le plus simple : pose la souris et parcours toute la page avec Tab, Shift+Tab, Entrée et Échap, en cochant chaque point au fur et à mesure :

1Checklist de navigation au clavier :
2[ ] Chaque élément interactif peut-il être atteint avec Tab ?
3[ ] L'ordre du focus est-il logique ?
4[ ] Le focus est-il toujours visible ?
5[ ] Les boîtes de dialogue modales piègent-elles le focus ?
6[ ] Une modale peut-elle être fermée avec la touche Échap ?
7[ ] Le lien d'évitement fonctionne-t-il correctement ?
8[ ] Les formulaires peuvent-ils être soumis avec Entrée ?
9[ ] Les menus déroulants peuvent-ils être parcourus avec les touches fléchées ?

Le test prend quelques minutes, mais il détecte ce qu'un outil automatique ne verra pas, par exemple un focus qui disparaît dans un menu caché. Envoie aussi un formulaire vide et vérifie si les messages te guident vers les champs erronés.

Le test au lecteur d'écran

Un lecteur d'écran est le seul moyen d'entendre une page comme l'entend une personne aveugle. Les lecteurs d'écran populaires :

  • NVDA (Windows, gratuit) - www.nvaccess.org
  • VoiceOver (macOS/iOS, intégré) - Cmd + F5
  • JAWS (Windows, payant) - standard professionnel
  • TalkBack (Android, intégré)

Pour commencer, VoiceOver ou NVDA, qui est gratuit, suffisent - écoute si les champs ont des noms qui ont du sens. La dernière étape, et la plus précieuse, ce sont les tests avec des utilisateurs en situation de handicap - personne ne connaît leurs besoins mieux qu'eux-mêmes.

Le test de zoom

Les personnes malvoyantes agrandissent la page au lieu de plisser les yeux devant un texte minuscule. Tu peux zoomer avec Ctrl et + (Cmd et + sur Mac) :

1Checklist du test de zoom :
2[ ] Zoome la page à 200 % - tout le contenu est-il visible ?
3[ ] Zoome à 400 % - la page fonctionne-t-elle toujours ?
4[ ] Le texte n'est-il pas coupé ou superposé ?
5[ ] Le défilement ne se fait-il que dans une seule direction ?

Les seuils viennent des WCAG : le critère 1.4.4 exige que le texte puisse être agrandi jusqu'à 200 % sans perte de contenu, et le critère 1.4.10 qu'il n'y ait pas de défilement dans deux directions à une largeur de 320 pixels CSS, ce qui correspond à 400 % sur un écran de 1280px.

Chrome DevTools - Accessibility

Le panneau Accessibility

Les DevTools te montrent comment le navigateur « traduit » un élément pour le lecteur d'écran. Sélectionne un élément dans le panneau Elements et ouvre l'onglet Accessibility :

1Chrome DevTools > Elements > Accessibility:
2- Name: "Fermer" (depuis aria-label)
3- Role: button
4- Focusable: true
5- Description: "Fermer la boîte de dialogue"

Name est le nom accessible de l'élément, et Role dit ce qu'il est. Un Name vide signifie que le lecteur n'a rien à lire - tu viens de trouver un bug.

La simulation des troubles de la vision

Les DevTools savent aussi montrer la page à travers les yeux d'une personne atteinte d'un trouble de la vision. Chrome DevTools > Rendering > Emulate vision deficiencies :

  • Protanopia (absence de rouge)
  • Deuteranopia (absence de vert)
  • Tritanopia (absence de bleu)
  • Blurred vision (vision floue)

Tu ouvres le panneau Rendering depuis le menu des DevTools (More tools). Active la protanopie et regarde si la bordure rouge de l'erreur se distingue encore.

L'inspection du contraste

Tu peux vérifier le contraste sans quitter les DevTools. Dans l'onglet Styles, clique sur le petit carré de couleur à côté de la propriété color :

1Chrome DevTools > Elements > Styles:
2- Clique sur le petit carré de couleur à côté de la propriété color
3- Le sélecteur de couleurs affichera le Contrast ratio
4- Coche à côté de AA = le texte atteint le seuil de 4.5:1
5- Coche à côté de AAA = il atteint aussi le seuil de 7:1
6- Pas de coche = contraste trop faible

Tu peux y déplacer la couleur jusqu'à ce que le contraste atteigne le seuil requis.

L'automatisation des tests a11y

eslint-plugin-jsx-a11y (React)

Quand tu commenceras à écrire du React dans le monde Mission spatiale, le linter ESLint avec le plugin jsx-a11y repérera les erreurs d'accessibilité pendant que tu écris encore ton code :

1{
2  "plugins": ["jsx-a11y"],
3  "rules": {
4    "jsx-a11y/alt-text": "error",
5    "jsx-a11y/anchor-has-content": "error",
6    "jsx-a11y/label-has-associated-control": "error",
7    "jsx-a11y/no-noninteractive-element-interactions": "warn"
8  }
9}

Chaque règle correspond à une vérification - alt-text signale une image sans texte alternatif, et label-has-associated-control un champ sans étiquette. Le niveau « error » traite un problème comme une erreur, alors que « warn » se contente d'avertir.

axe-core dans les tests

Tu peux aussi lancer le moteur axe-core dans des tests automatisés, pour que chaque modification du code soit vérifiée sans que tu aies à intervenir :

1<!-- Exemple de résultat d'un test axe-core : -->
2<!--
3  Rule: color-contrast
4  Description: Elements must have sufficient color contrast
5  Help: Fix any of the following:
6    Element has insufficient color contrast of 2.5:1
7    Expected minimum: 4.5:1
8  Target: .subtitle
9-->

La règle color-contrast a trouvé un texte dont le contraste est de 2.5:1 alors que 4.5:1 est exigé, et elle a indiqué le sélecteur .subtitle - tu sais exactement quoi corriger.

La checklist d'accessibilité - la liste complète

Pour finir, voici la liste de contrôle de tout le module, ordonnée depuis les fondations - la sémantique et la langue de la page - jusqu'aux attributs ARIA avancés :

1<!-- Structure HTML -->
2<!-- [ ] Hiérarchie de titres correcte (h1-h6) -->
3<!-- [ ] Balises sémantiques (header, nav, main, footer) -->
4<!-- [ ] Langue de la page (lang="fr") -->
5
6<!-- Images -->
7<!-- [ ] Texte alternatif pour les images informatives -->
8<!-- [ ] alt="" vide pour les images décoratives -->
9
10<!-- Navigation -->
11<!-- [ ] Lien d'évitement -->
12<!-- [ ] Focus visible -->
13<!-- [ ] Ordre de Tab logique -->
14
15<!-- Formulaires -->
16<!-- [ ] Étiquette pour chaque champ -->
17<!-- [ ] Messages d'erreur -->
18<!-- [ ] aria-required pour les champs obligatoires -->
19
20<!-- Couleur et contraste -->
21<!-- [ ] Contraste minimum 4.5:1 -->
22<!-- [ ] Information non véhiculée par la couleur seule -->
23
24<!-- Multimédia -->
25<!-- [ ] Sous-titres pour la vidéo -->
26<!-- [ ] Transcriptions pour l'audio -->
27
28<!-- ARIA -->
29<!-- [ ] aria-label pour les boutons à icône -->
30<!-- [ ] aria-live pour le contenu dynamique -->
31<!-- [ ] aria-expanded pour les éléments dépliables -->

Commence par le haut : sans sémantique et sans lang, même le meilleur ARIA ne servira à rien. Pour les boutons à icône, vérifie aussi que l'icône elle-même porte aria-hidden="true", afin que le lecteur ne lise que le nom fourni par aria-label.

Tester l'accessibilité, c'est comme vérifier que chaque couloir de la pyramide mène bien là où il doit - un contrôle systématique de chaque élément pour s'assurer que chaque visiteur atteindra sa destination. Dans le projet final de ce module, tu passeras cette liste en revue sur ta propre page.

Pratique

Parcours point par point la checklist interactive de l'éditeur ci-dessous :

Code de cette leçon : index.html
1<!DOCTYPE html>
2<html lang="en">
3<head>
4    <meta charset="UTF-8">
5    <meta name="viewport" content="width=device-width, initial-scale=1.0">
6    <title>Tests d'accessibilité - checklist</title>
7    <link rel="stylesheet" href="style.css">
8</head>
9<body>
10    <h1>Checklist des tests d'accessibilité</h1>
11
12    <section>
13        <h2>1. Test du clavier</h2>
14        <p>Navigue sur cette page en utilisant <kbd>Tab</kbd> et vérifie :</p>
15        <ul class="checklist">
16            <li><label><input type="checkbox"> Chaque élément interactif est atteignable avec Tab</label></li>
17            <li><label><input type="checkbox"> Le focus est visible sur chaque élément</label></li>
18            <li><label><input type="checkbox"> L'ordre du focus est logique</label></li>
19            <li><label><input type="checkbox"> Les boutons réagissent à Entrée et Espace</label></li>
20        </ul>
21    </section>
22
23    <section>
24        <h2>2. Test de la structure HTML</h2>
25        <ul class="checklist">
26            <li><label><input type="checkbox"> La page a une hiérarchie h1-h6 correcte</label></li>
27            <li><label><input type="checkbox"> Des balises sémantiques ont été utilisées</label></li>
28            <li><label><input type="checkbox"> La langue de la page est définie (lang="en")</label></li>
29            <li><label><input type="checkbox"> Tous les ID sont uniques</label></li>
30        </ul>
31    </section>
32
33    <section>
34        <h2>3. Test des images</h2>
35        <div class="test-area">
36            <figure>
37                <img src="https://placehold.co/300x200/d4af37/1a1a2e?text=Sphinx"
38                     alt="Le Grand Sphinx de Gizeh gardant les pyramides">
39                <figcaption>Le Grand Sphinx - image avec texte alt</figcaption>
40            </figure>
41            <img src="https://placehold.co/400x3/d4af37/d4af37" alt="">
42            <p><em>La ligne décorative ci-dessus a un alt=""</em></p>
43        </div>
44        <ul class="checklist">
45            <li><label><input type="checkbox"> Les images informatives ont un alt descriptif</label></li>
46            <li><label><input type="checkbox"> Les images décoratives ont un alt=""</label></li>
47        </ul>
48    </section>
49
50    <section>
51        <h2>4. Test du formulaire</h2>
52        <form class="test-form">
53            <div class="form-group">
54                <label for="test-name">Prénom :</label>
55                <input type="text" id="test-name" aria-required="true">
56            </div>
57            <div class="form-group">
58                <label for="test-email">E-mail :</label>
59                <input type="email" id="test-email"
60                       aria-describedby="test-email-hint">
61                <p id="test-email-hint" class="hint">Format : jean@example.com</p>
62            </div>
63            <button type="button" onclick="validateForm()">Vérifier le formulaire</button>
64            <div id="form-result" aria-live="polite"></div>
65        </form>
66        <ul class="checklist">
67            <li><label><input type="checkbox"> Chaque champ a une étiquette</label></li>
68            <li><label><input type="checkbox"> Les champs obligatoires sont marqués aria-required</label></li>
69            <li><label><input type="checkbox"> Les erreurs sont décrites par aria-describedby</label></li>
70        </ul>
71    </section>
72
73    <section>
74        <h2>5. Test du contraste</h2>
75        <div class="contrast-test">
76            <p class="pass-aa">Ce texte respecte WCAG AA (contraste > 4.5:1)</p>
77            <p class="fail">Ce texte NE respecte PAS les exigences (contraste < 3:1)</p>
78        </div>
79        <ul class="checklist">
80            <li><label><input type="checkbox"> Contraste du texte minimum 4.5:1</label></li>
81            <li><label><input type="checkbox"> Information pas uniquement par la couleur</label></li>
82        </ul>
83    </section>
84
85    <script>
86    function validateForm() {
87        const name = document.getElementById('test-name').value;
88        const result = document.getElementById('form-result');
89        if (!name) {
90            result.innerHTML = '<p class="error" role="alert">Remplis le champ Prénom !</p>';
91        } else {
92            result.innerHTML = '<p class="success">Formulaire valide !</p>';
93        }
94    }
95    </script>
96</body>
97</html>

Souviens-toi : l'outil automatique est le premier gardien à l'entrée de la pyramide, mais seul le parcours des couloirs avec un clavier et un lecteur d'écran montrera si chacun parvient jusqu'à la chambre.

Tu as repéré une erreur dans cette leçon ?

Teste tes connaissances

Réponds aux questions de cette leçon. Choisis une réponse pour voir tout de suite si elle est correcte.

  1. 1. Où peux-tu lancer l'outil Lighthouse pour tester l'accessibilité ?

  2. 2. Que fait la media query @media (prefers-reduced-motion: reduce) ?

Tâches pratiques dans le jeu

  • Tri vertical

    Range les étapes des tests d'accessibilité, des tests automatisés aux tests manuels :

  • Tri vertical

    Compose la structure correcte d'un élément figure avec une description :

  • Tri vertical

    Compose la media query correcte pour désactiver les animations :

  • Éditeur de code

    Teste le formulaire - clique sur Envoyer sans remplir les champs. Observe comment aria-invalid, aria-describedby et role="alert" communiquent les erreurs.

  • Clique dans l'ordre

    Compose un message d'erreur correct avec des attributs ARIA :

  • Tri vertical

    Range les éléments de la checklist a11y du plus important (fondamentaux) au plus avancé :

  • Tri horizontal

    Compose la syntaxe correcte d'un lien vers la page actuelle avec aria-current :

  • Clique dans l'ordre

    Compose un bouton correct avec une icône et aria-label :

  • Tri vertical

    Range les rôles de landmark dans l'ordre typique sur une page (du haut vers le bas) :

  • Éditeur de code

    Trouve et corrige les 8 erreurs d'accessibilité de cette page. Chaque erreur est signalée par un commentaire.

Articles utiles