Couverture de la page par thématique
ThématiqueTestsDémo statique axeCollecteurPartiel Manueln/a
1. Images5959502520
2. Cadres2210010
3. Couleurs151340092
4. Multimédia2525003220
5. Tableaux1515002130
6. Liens6610050
7. Scripts111120090
8. Éléments obligatoires13830145
9. Structuration de l'information9931140
10. Présentation de l'information2929202250
11. Formulaires3433310291
12. Navigation1911001108
13. Consultation211340098
Total25823428 21219224

1. Images (59 tests)

Les images doivent posséder une alternative textuelle pertinente (ou être signalées décoratives), y compris les images réactives, vectorielles, objet, embarquées et canvas.

1.1 — Chaque image porteuse d'information a-t-elle une alternative textuelle ?

1.1.1 axe · image-alt

Chaque image (balise <img> ou balise possédant l'attribut WAI-ARIA role="img") porteuse d'information a-t-elle une alternative textuelle ?

Démo volontairement fautive

Voir le code source du piège
<img src="img/info.png" width="120" height="80">

Ce qui ne va pas : L'image illustre un concept expliqué dans le texte : elle est porteuse d'information. Sans attribut alt, le lecteur d'écran lit le nom du fichier et aucune information n'est transmise.

Comment corriger : Ajouter un alt qui décrit le contenu informatif : <img src="img/info.png" alt="Icône d'information">. Si l'image n'apportait aucune information, elle serait décorative et mériterait alt="".

WCAG :
  • 1.1.1 Non-text Content (A)

1.1.2 axe · area-alt

Chaque zone d'une image réactive (balise <area>) porteuse d'information a-t-elle une alternative textuelle ?

Démo volontairement fautive

Carte des régions
Voir le code source du piège
<img src="img/info.png" usemap="#carte" alt="Carte des régions" width="120" height="80"><map name="carte"><area shape="rect" coords="0,0,60,80" href="page2.html"></map>

Ce qui ne va pas : La zone cliquable (<area>) de l'image réactive est porteuse d'information mais n'a pas d'attribut alt. Un utilisateur de lecteur d'écran ne sait pas où mène ce lien.

Comment corriger : Ajouter un alt à chaque zone : <area shape="rect" coords="0,0,60,80" href="page2.html" alt="Région Nord">. L'alternative doit décrire la destination ou la fonction de la zone.

WCAG :
  • 1.1.1 Non-text Content (A)

1.1.3 axe · input-image-alt

Chaque bouton de type image (balise <input> avec l'attribut type="image") a-t-il une alternative textuelle ?

Démo volontairement fautive

Voir le code source du piège
<input type="image" src="img/logo.png" width="100" height="40">

Ce qui ne va pas : Le bouton de type image n'a pas d'attribut alt : son nom accessible est vide ou dérivé du nom de fichier. Un lecteur d'écran annonce « bouton » sans préciser son action.

Comment corriger : Ajouter un alt décrivant l'action : <input type="image" src="img/logo.png" alt="Valider la commande" width="100" height="40">.

WCAG :
  • 1.1.1 Non-text Content (A)

1.1.4 partiel

Chaque zone cliquable d’une image réactive côté serveur est-elle doublée d’un mécanisme utilisable quel que soit le dispositif de pointage utilisé et permettant d'accéder à la même destination ?

Démo volontairement fautive

Carte interactive
Voir le code source du piège
<a href="page2.html"><img src="img/info.png" ismap alt="Carte interactive" width="120" height="80"></a>

Ce qui ne va pas : L'attribut ismap fait de l'image une image réactive côté serveur : les coordonnées du clic sont envoyées au serveur, ce qui est inutilisable au clavier ou sans souris. Aucun mécanisme alternatif ne donne accès aux mêmes destinations. axe-core signale un doute (résultat incomplete) : la confirmation humaine reste nécessaire.

Comment corriger : Remplacer l'image réactive serveur par une image réactive côté client (usemap + <map>) ou par de simples liens texte, utilisables quel que soit le dispositif de pointage.

WCAG :
  • 1.1.1 Non-text Content (A)

1.1.5 axe · svg-img-alt

Chaque image vectorielle (balise <svg>) porteuse d'information, vérifie-t-elle ces conditions ? La balise <svg> possède un attribut WAI-ARIA role="img" ; La balise <svg> a une alternative textuelle.

Démo volontairement fautive

Voir le code source du piège
<svg role="img" width="40" height="40"><circle cx="20" cy="20" r="15" fill="#00f"></circle></svg>

Ce qui ne va pas : L'image vectorielle est porteuse d'information et expose bien role="img", mais elle n'a aucune alternative textuelle (aria-label, <title> enfant ou texte). Les technologies d'assistance annoncent une image sans nom.

Comment corriger : Ajouter role="img" et une alternative : <svg role="img" aria-label="Point bleu" width="40" height="40">…</svg>, ou un <title> en premier enfant.

WCAG :
  • 1.1.1 Non-text Content (A)

1.1.6 axe · object-alt

Chaque image objet (balise <object> avec l'attribut type="image/…") porteuse d'information, vérifie-t-elle une de ces conditions ? La balise <object> possède une alternative textuelle et un attribut role="img" ; L'élément <object> est immédiatement suivi d'un lien ou bouton adjacent permettant d'accéder à un contenu alternatif ; Un mécanisme permet à l'utilisateur de remplacer l'élément <object> par un contenu alternatif.

Démo volontairement fautive

Voir le code source du piège
<object type="image/png" data="img/info.png" width="120" height="80"></object>

Ce qui ne va pas : L'image objet est porteuse d'information mais la balise <object> est vide : aucune alternative textuelle n'est fournie.

Comment corriger : Ajouter une alternative : <object type="image/png" data="img/info.png" role="img" aria-label="Icône d'information" width="120" height="80"></object>, ou du texte de remplacement entre <object> et </object>.

WCAG :
  • 1.1.1 Non-text Content (A)

1.1.7 manuel

Chaque image embarquée (balise <embed> avec l'attribut type="image/…") porteuse d'information, vérifie-t-elle une de ces conditions ? La balise <embed> possède une alternative textuelle et un attribut role="img" ; L'élément <embed> est immédiatement suivi d'un lien ou bouton adjacent permettant d'accéder à un contenu alternatif ; Un mécanisme permet à l'utilisateur de remplacer l'élément <embed> par un contenu alternatif.

Démo volontairement fautive

Voir le code source du piège
<embed type="image/png" src="img/info.png" width="120" height="80">

Ce qui ne va pas : L'image embarquée (<embed>) est porteuse d'information mais ne possède aucune alternative textuelle ni contenu alternatif accessible.

Comment corriger : Fournir une alternative (aria-label) sur la balise, ou remplacer <embed> par un <img> avec alt, plus simple et mieux supporté. Aucune règle axe-core active ne couvre <embed> : vérification manuelle.

WCAG :
  • 1.1.1 Non-text Content (A)

1.1.8 manuel

Chaque image bitmap (balise <canvas>) porteuse d'information, vérifie-t-elle une de ces conditions ? La balise <canvas> possède une alternative textuelle et un attribut role="img" ; Un contenu alternatif est présent entre les balises <canvas> et </canvas> ; L'élément <canvas> est immédiatement suivi d'un lien ou bouton adjacent permettant d'accéder à un contenu alternatif ; Un mécanisme permet à l'utilisateur de remplacer l'élément <canvas> par un contenu alternatif.

Démo volontairement fautive

Voir le code source du piège
<canvas width="120" height="80"></canvas>

Ce qui ne va pas : L'image bitmap (<canvas>) est porteuse d'information mais ne possède ni alternative textuelle ni contenu de remplacement entre les balises.

Comment corriger : Ajouter un contenu alternatif : <canvas role="img" aria-label="Icône d'information" width="120" height="80">Icône d'information</canvas>. Aucune règle axe-core active ne couvre <canvas> : vérification manuelle.

WCAG :
  • 1.1.1 Non-text Content (A)

1.2 — Chaque image de décoration est-elle correctement ignorée par les technologies d'assistance ?

1.2.1 manuel

Chaque image (balise <img>) de décoration, sans légende, vérifie-t-elle une de ces conditions ? La balise <img> possède un attribut alt vide (alt="") et est dépourvue de tout autre attribut permettant de fournir une alternative textuelle ; La balise <img> possède un attribut WAI-ARIA aria-hidden="true" ou role="presentation".

Démo volontairement fautive

Décoration
Voir le code source du piège
<img src="img/deco.png" alt="Décoration" width="80" height="40">

Ce qui ne va pas : L'image est purement décorative mais son alt contient du texte : elle sera annoncée par les lecteurs d'écran et polluera la navigation.

Comment corriger : Vider l'alternative : <img src="img/deco.png" alt="" width="80" height="40">, ou ajouter aria-hidden="true". Aucune règle axe active ne détecte ce cas (la règle image-redundant-alt est exclue) : vérification manuelle.

WCAG :
  • 1.1.1 Non-text Content (A)
  • 4.1.2 Name, Role, Value (A)

1.2.2 manuel

Chaque zone non cliquable (balise <area> sans attribut href) de décoration, vérifie-t-elle une de ces conditions ? La balise <area> possède un attribut alt vide (alt="") et est dépourvue de tout autre attribut permettant de fournir une alternative textuelle ; La balise <area> possède un attribut WAI-ARIA aria-hidden="true" ou role="presentation".

Démo volontairement fautive

zone décorative
Voir le code source du piège
<img src="img/deco.png" usemap="#dec" alt="" width="80" height="40"><map name="dec"><area shape="rect" coords="0,0,40,40" alt="zone décorative"></map>

Ce qui ne va pas : La zone non cliquable (<area> sans href) est décorative mais possède un alt non vide : elle sera restituée inutilement par les technologies d'assistance.

Comment corriger : Mettre alt="" sur la zone décorative ou aria-hidden="true". La conformité ne peut être jugée que manuellement.

WCAG :
  • 1.1.1 Non-text Content (A)
  • 4.1.2 Name, Role, Value (A)

1.2.3 manuel

Chaque image objet (balise <object> avec l'attribut type="image/…") de décoration, sans légende, vérifie-t-elle ces conditions ? La balise <object> possède un attribut WAI-ARIA aria-hidden="true" ; La balise <object> est dépourvue d'alternative textuelle ; Il n'y a aucun texte faisant office d'alternative textuelle entre <object> et </object>.

Démo volontairement fautive

Élément décoratif
Voir le code source du piège
<object type="image/png" data="img/deco.png" width="80" height="40">Élément décoratif</object>

Ce qui ne va pas : L'image objet est décorative mais contient un texte alternatif entre <object> et </object> : elle ne sera pas ignorée par les technologies d'assistance.

Comment corriger : Masquer l'image : <object type="image/png" data="img/deco.png" aria-hidden="true" width="80" height="40"></object>, sans aucun texte à l'intérieur.

WCAG :
  • 1.1.1 Non-text Content (A)
  • 4.1.2 Name, Role, Value (A)

1.2.4 manuel

Chaque image vectorielle (balise <svg>) de décoration, sans légende, vérifie-t-elle ces conditions ? La balise <svg> possède un attribut WAI-ARIA aria-hidden="true" ; La balise <svg> et ses enfants sont dépourvus d'alternative textuelle ; Les balises <title> et <desc> sont absentes ou vides ; La balise <svg> et ses enfants sont dépourvus d'attribut title.

Démo volontairement fautive

Forme décorative
Voir le code source du piège
<svg width="40" height="40"><title>Forme décorative</title><circle cx="20" cy="20" r="15" fill="#ccc"></circle></svg>

Ce qui ne va pas : L'image vectorielle est décorative mais possède un <title> : les technologies d'assistance l'annonceront alors qu'elle n'apporte aucune information.

Comment corriger : Ajouter aria-hidden="true" et retirer tout <title>, <desc> ou attribut title. Vérification manuelle.

WCAG :
  • 1.1.1 Non-text Content (A)
  • 4.1.2 Name, Role, Value (A)

1.2.5 manuel

Chaque image bitmap (balise <canvas>) de décoration, sans légende, vérifie-t-elle ces conditions ? La balise <canvas> possède un attribut WAI-ARIA aria-hidden="true" ; La balise <canvas> et ses enfants sont dépourvus d'alternative textuelle ; Il n'y a aucun texte faisant office d'alternative textuelle entre <canvas> et </canvas>.

Démo volontairement fautive

Élément décoratif
Voir le code source du piège
<canvas width="80" height="40">Élément décoratif</canvas>

Ce qui ne va pas : L'image bitmap est décorative mais un texte de remplacement est présent entre <canvas> et </canvas> : il sera restitué par les technologies d'assistance.

Comment corriger : Ajouter aria-hidden="true" et supprimer tout contenu textuel entre les balises. Vérification manuelle.

WCAG :
  • 1.1.1 Non-text Content (A)
  • 4.1.2 Name, Role, Value (A)

1.2.6 manuel

Chaque image embarquée (balise <embed> avec l'attribut type="image/…") de décoration, sans légende, vérifie-t-elle ces conditions ? La balise <embed> possède un attribut WAI-ARIA aria-hidden="true" ; La balise <embed> et ses enfants sont dépourvus d'alternative textuelle.

Démo volontairement fautive

Voir le code source du piège
<embed type="image/png" src="img/deco.png" aria-label="Décoration" width="80" height="40">

Ce qui ne va pas : L'image embarquée est décorative mais porte une alternative textuelle (aria-label) : elle sera annoncée inutilement.

Comment corriger : Ajouter aria-hidden="true" et retirer toute alternative textuelle. Aucune règle axe active ne couvre <embed> : vérification manuelle.

WCAG :
  • 1.1.1 Non-text Content (A)
  • 4.1.2 Name, Role, Value (A)

1.3 — Pour chaque image porteuse d'information ayant une alternative textuelle, cette alternative est-elle pertinente (hors cas particuliers) ?

1.3.1 manuel

Pour chaque image (balise <img> ou balise possédant l'attribut WAI-ARIA role="img") porteuse d'information, ayant une alternative textuelle, cette alternative est-elle pertinente (hors cas particuliers) ? S'il est présent, le contenu de l'attribut alt est pertinent ; S'il est présent, le contenu de l'attribut title est pertinent ; S'il est présent, le contenu de l'attribut WAI-ARIA aria-label est pertinent ; S'il est présent, le passage de texte associé via l'attribut WAI-ARIA aria-labelledby est pertinent.

Démo volontairement fautive

Image
Voir le code source du piège
<img src="img/info.png" alt="Image" width="120" height="80">

Ce qui ne va pas : L'alternative « Image » ne transmet aucune information sur le contenu de l'image : elle est générique et n'aide pas l'utilisateur de lecteur d'écran.

Comment corriger : Rédiger une alternative qui décrit précisément l'information véhiculée, par exemple alt="Icône d'information". La pertinence est un jugement humain.

WCAG :
  • 1.1.1 Non-text Content (A)
  • 4.1.2 Name, Role, Value (A)

1.3.2 manuel

Pour chaque zone (balise <area>) d'une image réactive porteuse d'information, ayant une alternative textuelle, cette alternative est-elle pertinente (hors cas particuliers) ? S'il est présent, le contenu de l'attribut alt est pertinent ; S'il est présent, le contenu de l'attribut title est pertinent ; S'il est présent, le contenu de l'attribut WAI-ARIA aria-label est pertinent ; S'il est présent, le passage de texte associé via l'attribut WAI-ARIA aria-labelledby est pertinent.

Démo volontairement fautive

Carte des régionsCliquez
Voir le code source du piège
<img src="img/info.png" usemap="#carte" alt="Carte des régions" width="120" height="80"><map name="carte"><area shape="rect" coords="0,0,60,80" href="page2.html" alt="Cliquez"></map>

Ce qui ne va pas : L'alternative « Cliquez » de la zone ne décrit ni la destination ni la fonction du lien ; elle est inexploitable pour un utilisateur de lecteur d'écran.

Comment corriger : Décrire la destination : alt="Région Nord". La pertinence de l'alternative relève de la vérification humaine.

WCAG :
  • 1.1.1 Non-text Content (A)
  • 4.1.2 Name, Role, Value (A)

1.3.3 manuel

Pour chaque bouton de type image (balise <input> avec l'attribut type="image"), ayant une alternative textuelle, cette alternative est-elle pertinente (hors cas particuliers) ? S'il est présent, le contenu de l'attribut alt est pertinent ; S'il est présent, le contenu de l'attribut title est pertinent ; S'il est présent, le contenu de l'attribut WAI-ARIA aria-label est pertinent ; S'il est présent, le passage de texte associé via l'attribut WAI-ARIA aria-labelledby est pertinent.

Démo volontairement fautive

Voir le code source du piège
<input type="image" src="img/logo.png" alt="logo" width="100" height="40">

Ce qui ne va pas : Le bouton image décrit l'image (« logo ») au lieu de son action : l'utilisateur ne sait pas ce qui se passe en cliquant.

Comment corriger : Décrire l'action du bouton : alt="Valider la commande". La pertinence se vérifie manuellement.

WCAG :
  • 1.1.1 Non-text Content (A)
  • 4.1.2 Name, Role, Value (A)

1.3.4 manuel

Pour chaque image objet (balise <object> avec l'attribut type="image/…") porteuse d'information, ayant une alternative textuelle ou un contenu alternatif, cette alternative est-elle pertinente (hors cas particuliers) ? S'il est présent, le contenu de l'attribut title est pertinent ; S'il est présent, le contenu de l'attribut WAI-ARIA aria-label est pertinent ; S'il est présent, le passage de texte associé via l'attribut WAI-ARIA aria-labelledby est pertinent ; S'il est présent le contenu alternatif est pertinent.

Démo volontairement fautive

Un graphique
Voir le code source du piège
<object type="image/png" data="img/chart.png" width="160" height="100">Un graphique</object>

Ce qui ne va pas : Le contenu alternatif « Un graphique » est trop vague : il n'apporte pas l'information portée par le graphique (valeurs, tendance…).

Comment corriger : Rédiger un contenu alternatif qui restitue l'information (ex. « Ventes en hausse de 12 % au 3e trimestre »). La pertinence est un jugement humain.

WCAG :
  • 1.1.1 Non-text Content (A)
  • 4.1.2 Name, Role, Value (A)

1.3.5 manuel

Pour chaque image embarquée (balise <embed> avec l'attribut type="image/…") porteuse d'information, ayant une alternative textuelle ou un contenu alternatif, cette alternative est-elle pertinente (hors cas particuliers) ? S'il est présent, le contenu de l'attribut title est pertinent ; S'il est présent, le contenu de l'attribut WAI-ARIA aria-label est pertinent ; S'il est présent, le passage de texte associé via l'attribut WAI-ARIA aria-labelledby est pertinent ; S'il est présent le contenu alternatif est pertinent.

Démo volontairement fautive

Voir le code source du piège
<embed type="image/png" src="img/chart.png" aria-label="Graphique" width="160" height="100">

Ce qui ne va pas : L'alternative « Graphique » n'indique ni ce que mesure le graphique ni sa conclusion ; elle ne remplace pas l'information visuelle.

Comment corriger : Fournir une alternative informative, ou un lien adjacent vers un tableau de données. Vérification manuelle.

WCAG :
  • 1.1.1 Non-text Content (A)
  • 4.1.2 Name, Role, Value (A)

1.3.6 manuel

Pour chaque image vectorielle (balise <svg>) porteuse d'information, ayant une alternative textuelle, cette alternative est-elle pertinente (hors cas particuliers) ? S'il est présent, le contenu de l'élément <title> est pertinent ; S'il est présent, le contenu de l'attribut WAI-ARIA aria-label est pertinent ; S'il est présent, le passage de texte associé via l'attribut WAI-ARIA aria-labelledby est pertinent.

Démo volontairement fautive

logo
Voir le code source du piège
<svg role="img" width="40" height="40"><title>logo</title><circle cx="20" cy="20" r="15" fill="#00f"></circle></svg>

Ce qui ne va pas : Le <title> « logo » ne décrit pas l'information portée par l'image vectorielle ; il est générique et non pertinent.

Comment corriger : Remplacer par une alternative qui décrit le contenu informatif (ex. <title>Point bleu indiquant la position du curseur</title>). Vérification manuelle.

WCAG :
  • 1.1.1 Non-text Content (A)
  • 4.1.2 Name, Role, Value (A)

1.3.7 manuel

Pour chaque image bitmap (balise <canvas>) porteuse d'information, ayant une alternative textuelle ou un contenu alternatif, cette alternative est-elle pertinente (hors cas particuliers) ? S'il est présent, le contenu de l'attribut title est pertinent ; S'il est présent, le contenu de l'attribut WAI-ARIA aria-label est pertinent ; S'il est présent, le passage de texte associé via l'attribut WAI-ARIA aria-labelledby est pertinent ; S'il est présent le contenu alternatif est pertinent.

Démo volontairement fautive

Graphique
Voir le code source du piège
<canvas role="img" aria-label="Graphique" width="160" height="100">Graphique</canvas>

Ce qui ne va pas : L'alternative « Graphique » est trop générique : elle ne restitue pas les données représentées dans le <canvas>.

Comment corriger : Décrire les données essentielles (ex. « Ventes 2024 : 120 k€, en hausse de 10 % »). La pertinence est un jugement humain.

WCAG :
  • 1.1.1 Non-text Content (A)
  • 4.1.2 Name, Role, Value (A)

1.3.8 manuel

Pour chaque image bitmap (balise <canvas>) porteuse d'information et ayant un contenu alternatif entre <canvas> et </canvas>, ce contenu alternatif est-il correctement restitué par les technologies d'assistance ?

Démo volontairement fautive

Ventes en hausse
Voir le code source du piège
<canvas role="img" width="160" height="100">Ventes en hausse</canvas>

Ce qui ne va pas : Le contenu alternatif entre <canvas> et </canvas> n'est pas correctement restitué par les technologies d'assistance : la plupart ignorent le contenu interne des <canvas>.

Comment corriger : Préférer aria-label ou aria-labelledby sur le <canvas>, ou un passage de texte hors de la balise. La restitution réelle doit être testée avec des lecteurs d'écran (manuel).

WCAG :
  • 1.1.1 Non-text Content (A)
  • 4.1.2 Name, Role, Value (A)

1.3.9 manuel

Pour chaque image porteuse d'information et ayant une alternative textuelle, l'alternative textuelle est-elle courte et concise (hors cas particuliers) ?

Démo volontairement fautive

Une icône d'information bleue avec un cercle blanc au centre qui attire l'attention de l'utilisateur sur le caractère important de ce message
Voir le code source du piège
<img src="img/info.png" alt="Une icône d'information bleue avec un cercle blanc au centre qui attire l'attention de l'utilisateur sur le caractère important de ce message" width="120" height="80">

Ce qui ne va pas : L'alternative textuelle est beaucoup trop longue pour une image simple : elle alourdit la lecture linéaire des lecteurs d'écran.

Comment corriger : Raccourcir l'alternative à l'essentiel (alt="Icône d'information") et, si besoin, déplacer le détail dans une description détaillée (longdesc ou lien adjacent).

WCAG :
  • 1.1.1 Non-text Content (A)
  • 4.1.2 Name, Role, Value (A)

1.4 — Pour chaque image utilisée comme CAPTCHA ou comme image-test, ayant une alternative textuelle, cette alternative permet-elle d'identifier la nature et la fonction de l'image ?

1.4.1 manuel

Pour chaque image (balise <img>) utilisée comme CAPTCHA ou comme image-test, ayant une alternative textuelle, cette alternative est-elle pertinente ? S'il est présent, le contenu de l'attribut alt est pertinent ; S'il est présent, le contenu de l'attribut title est pertinent ; S'il est présent, le contenu de l'attribut WAI-ARIA aria-label est pertinent ; S'il est présent, le passage de texte associé via l'attribut WAI-ARIA aria-labelledby est pertinent.

Démo volontairement fautive

Image de sécurité
Voir le code source du piège
<img src="img/info.png" alt="Image de sécurité" width="120" height="80">

Ce qui ne va pas : L'image sert de CAPTCHA mais son alternative « Image de sécurité » n'identifie pas la nature et la fonction du test (ex. « Saisissez les caractères affichés »).

Comment corriger : Donner une alternative fonctionnelle : alt="Saisissez les 4 caractères affichés dans l'image". La pertinence d'un CAPTCHA s'évalue manuellement.

WCAG :
  • 1.1.1 Non-text Content (A)

1.4.2 manuel

Pour chaque zone (balise <area>) d'une image réactive utilisée comme CAPTCHA ou comme image-test, ayant une alternative textuelle, cette alternative est-elle pertinente ? S'il est présent, le contenu de l'attribut alt est pertinent ; S'il est présent, le contenu de l'attribut title est pertinent ; S'il est présent, le contenu de l'attribut WAI-ARIA aria-label est pertinent ; S'il est présent, le passage de texte associé via l'attribut WAI-ARIA aria-labelledby est pertinent.

Démo volontairement fautive

Cliquez sur la bonne zonezone
Voir le code source du piège
<img src="img/info.png" usemap="#capt" alt="Cliquez sur la bonne zone" width="120" height="80"><map name="capt"><area shape="rect" coords="0,0,60,80" href="#" alt="zone"></map>

Ce qui ne va pas : La zone du CAPTCHA a une alternative « zone » qui n'identifie ni la nature ni la fonction de l'image-test.

Comment corriger : Remplacer par une alternative explicite, ex. alt="Cliquez sur la zone contenant le symbole demandé". Vérification humaine.

WCAG :
  • 1.1.1 Non-text Content (A)

1.4.3 manuel

Pour chaque bouton de type image (balise <input> avec l'attribut type="image") utilisé comme CAPTCHA ou comme image-test, ayant une alternative textuelle, cette alternative est-elle pertinente ? S'il est présent, le contenu de l'attribut alt est pertinent ; S'il est présent, le contenu de l'attribut title est pertinent ; S'il est présent, le contenu de l'attribut WAI-ARIA aria-label est pertinent ; S'il est présent, le passage de texte associé via l'attribut WAI-ARIA aria-labelledby est pertinent.

Démo volontairement fautive

Voir le code source du piège
<input type="image" src="img/info.png" alt="captcha" width="120" height="80">

Ce qui ne va pas : Le bouton-image CAPTCHA a une alternative « captcha » qui n'explique pas la tâche demandée à l'utilisateur.

Comment corriger : Décrire la fonction : alt="Valider le code de sécurité". Vérification manuelle.

WCAG :
  • 1.1.1 Non-text Content (A)

1.4.4 manuel

Pour chaque image objet (balise <object> avec l'attribut type="image/…") utilisée comme CAPTCHA ou comme image-test, ayant une alternative textuelle ou un contenu alternatif, cette alternative est-elle pertinente ? S'il est présent, le contenu de l'attribut title est pertinent ; S'il est présent, le contenu de l'attribut WAI-ARIA aria-label est pertinent ; S'il est présent, le passage de texte associé via l'attribut WAI-ARIA aria-labelledby est pertinent ; S'il est présent, le contenu alternatif est pertinent.

Démo volontairement fautive

code
Voir le code source du piège
<object type="image/png" data="img/info.png" width="120" height="80">code</object>

Ce qui ne va pas : Le CAPTCHA <object> a un contenu alternatif « code » qui n'identifie pas la nature du test ni la réponse attendue.

Comment corriger : Fournir une alternative décrivant la fonction (ex. « Saisissez le code affiché ») ou une solution d'accès alternative. Vérification manuelle.

WCAG :
  • 1.1.1 Non-text Content (A)

1.4.5 manuel

Pour chaque image embarquée (balise <embed> avec l'attribut type="image/…") utilisée comme CAPTCHA ou comme image-test, ayant une alternative textuelle ou un contenu alternatif, cette alternative est-elle pertinente ? S'il est présent, le contenu de l'attribut title est pertinent ; S'il est présent, le contenu de l'attribut WAI-ARIA aria-label est pertinent ; S'il est présent, le passage de texte associé via l'attribut WAI-ARIA aria-labelledby est pertinent ; S'il est présent, le contenu alternatif est pertinent.

Démo volontairement fautive

Voir le code source du piège
<embed type="image/png" src="img/info.png" aria-label="test" width="120" height="80">

Ce qui ne va pas : L'alternative « test » du CAPTCHA embarqué n'identifie ni la nature ni la fonction de l'image-test.

Comment corriger : Décrire précisément la tâche (ex. « Saisissez les caractères visibles ») et proposer une alternative non graphique. Vérification manuelle.

WCAG :
  • 1.1.1 Non-text Content (A)

1.4.6 manuel

Pour chaque image vectorielle (balise <svg>) utilisée comme CAPTCHA ou comme image-test, ayant une alternative textuelle, cette alternative est-elle pertinente ? S'il est présent, le contenu de l'attribut title est pertinent ; S'il est présent, le contenu de l'attribut WAI-ARIA aria-label est pertinent ; S'il est présent, le passage de texte associé via l'attribut WAI-ARIA aria-labelledby est pertinent.

Démo volontairement fautive

captcha
Voir le code source du piège
<svg role="img" width="120" height="80"><title>captcha</title><rect width="120" height="80" fill="#eee"></rect></svg>

Ce qui ne va pas : Le <title> « captcha » de l'image vectorielle n'indique pas la tâche demandée (saisie des caractères, choix d'image…).

Comment corriger : Rédiger un aria-label ou <title> fonctionnel : « Saisissez les caractères affichés ». Vérification humaine.

WCAG :
  • 1.1.1 Non-text Content (A)

1.4.7 manuel

Pour chaque image bitmap (balise <canvas>) utilisée comme CAPTCHA ou comme image-test, ayant une alternative textuelle ou un contenu alternatif, cette alternative est-elle pertinente ? S'il est présent, le contenu de l'attribut title est pertinent ; S'il est présent, le contenu de l'attribut WAI-ARIA aria-label est pertinent ; S'il est présent, le passage de texte associé via l'attribut WAI-ARIA aria-labelledby est pertinent ; S'il est présent, le contenu alternatif est pertinent.

Démo volontairement fautive

captcha
Voir le code source du piège
<canvas role="img" aria-label="captcha" width="120" height="80">captcha</canvas>

Ce qui ne va pas : L'alternative « captcha » de l'image bitmap n'identifie pas la nature et la fonction du test.

Comment corriger : Décrire la tâche attendue et, surtout, proposer une solution d'accès non graphique. Vérification manuelle.

WCAG :
  • 1.1.1 Non-text Content (A)

1.5 — Pour chaque image utilisée comme CAPTCHA, une solution d'accès alternatif au contenu ou à la fonction du CAPTCHA est-elle présente ?

1.5.1 manuel

Chaque image (balises <img>, <area>, <object>, <embed>, <svg>, <canvas> ou possédant un attribut WAI-ARIA role="img") utilisée comme CAPTCHA vérifie-t-elle une de ces conditions ? Il existe une autre forme de CAPTCHA non graphique, au moins ; Il existe une autre solution d'accès à la fonctionnalité qui est sécurisée par le CAPTCHA.

Démo volontairement fautive

Saisissez les caractères affichés
Voir le code source du piège
<img src="img/info.png" alt="Saisissez les caractères affichés" width="120" height="80">

Ce qui ne va pas : Le CAPTCHA graphique n'est accompagné d'aucune autre forme de CAPTCHA (audio, logique…) ni d'une autre solution d'accès à la fonctionnalité protégée.

Comment corriger : Proposer au moins un CAPTCHA non graphique (ex. question logique) ou une solution d'accès alternative (ex. assistance par courriel). Vérification manuelle.

WCAG :
  • 1.1.1 Non-text Content (A)

1.5.2 manuel

Chaque bouton associé à une image (balise input avec l'attribut type="image") utilisée comme CAPTCHA vérifie-t-il une de ces conditions ? Il existe une autre forme de CAPTCHA non graphique, au moins ; Il existe une autre solution d'accès à la fonctionnalité sécurisée par le CAPTCHA.

Démo volontairement fautive

Voir le code source du piège
<input type="image" src="img/info.png" alt="Valider le code de sécurité" width="120" height="80">

Ce qui ne va pas : Le bouton-image CAPTCHA n'est doublé d'aucune solution d'accès alternative à la fonctionnalité sécurisée.

Comment corriger : Ajouter une autre forme de CAPTCHA non graphique ou un accès alternatif à la fonctionnalité. Vérification manuelle.

WCAG :
  • 1.1.1 Non-text Content (A)

1.6 — Chaque image porteuse d'information a-t-elle, si nécessaire, une description détaillée ?

1.6.1 manuel

Chaque image (balise <img>) porteuse d'information, qui nécessite une description détaillée, vérifie-t-elle une de ces conditions ? Il existe un attribut longdesc qui donne l'adresse (URL) d'une page ou d'un emplacement dans la page contenant la description détaillée ; Il existe une alternative textuelle contenant la référence à une description détaillée adjacente à l'image ; Il existe un lien ou un bouton adjacent permettant d'accéder à la description détaillée.

Démo volontairement fautive

Ventes par trimestre
Voir le code source du piège
<img src="img/chart.png" alt="Ventes par trimestre" width="160" height="100">

Ce qui ne va pas : Le graphique est complexe : son alt résume le sujet mais ne transmet pas les données (valeurs, tendances). Aucune description détaillée (longdesc, lien adjacent…) n'est fournie.

Comment corriger : Ajouter une description détaillée : lien adjacent « Description du graphique » vers un tableau de données, ou attribut longdesc.

WCAG :
  • 1.1.1 Non-text Content (A)

1.6.2 manuel

Chaque image objet (balise <object> avec l'attribut type="image/…") porteuse d'information, qui nécessite une description détaillée, vérifie-t-elle une de ces conditions ? Il existe une alternative textuelle contenant la référence à une description détaillée adjacente à l'image ; Il existe un lien ou un bouton adjacent permettant d'accéder à la description détaillée.

Démo volontairement fautive

Ventes par trimestre
Voir le code source du piège
<object type="image/png" data="img/chart.png" width="160" height="100">Ventes par trimestre</object>

Ce qui ne va pas : L'image objet complexe n'a qu'une alternative courte : aucune description détaillée (texte adjacent ou lien) ne restitue les données du graphique.

Comment corriger : Ajouter un lien ou bouton adjacent vers une description détaillée, ou une alternative textuelle signalant une description adjacente.

WCAG :
  • 1.1.1 Non-text Content (A)

1.6.3 manuel

Chaque image embarquée (balise <embed>) porteuse d'information, qui nécessite une description détaillée, vérifie-t-elle une de ces conditions ? Il existe une alternative textuelle contenant la référence à une description détaillée adjacente à l'image ; Il existe un lien ou un bouton adjacent permettant d'accéder à la description détaillée.

Démo volontairement fautive

Voir le code source du piège
<embed type="image/png" src="img/chart.png" aria-label="Ventes par trimestre" width="160" height="100">

Ce qui ne va pas : L'image embarquée complexe ne dispose que d'une alternative courte ; aucune description détaillée n'est accessible.

Comment corriger : Adjoindre un lien « Description détaillée » vers un tableau de données équivalent. Vérification manuelle.

WCAG :
  • 1.1.1 Non-text Content (A)

1.6.4 manuel

Chaque bouton de type image (balise <input> avec l'attribut type="image") porteur d'information, qui nécessite une description détaillée, vérifie-t-elle une de ces conditions ? Il existe une alternative textuelle contenant la référence à une description détaillée adjacente à l'image ; Il existe un lien ou un bouton adjacent permettant d'accéder à la description détaillée ; Il existe un attribut WAI-ARIA aria-describedby associant un passage de texte faisant office de description détaillée.

Démo volontairement fautive

Voir le code source du piège
<input type="image" src="img/chart.png" alt="Ventes par trimestre" width="160" height="100">

Ce qui ne va pas : Le bouton-image affiche un graphique complexe sans description détaillée : les données ne sont accessibles ni via aria-describedby ni via un lien adjacent.

Comment corriger : Associer une description via aria-describedby pointant vers un passage de texte, ou ajouter un lien adjacent.

WCAG :
  • 1.1.1 Non-text Content (A)

1.6.5 manuel

Chaque image vectorielle (balise <svg>) porteuse d'information, qui nécessite une description détaillée, vérifie-t-elle une de ces conditions ? Il existe un attribut WAI-ARIA aria-label contenant l'alternative textuelle et une référence à une description détaillée adjacente ; Il existe un attribut WAI-ARIA aria-labelledby associant un passage de texte faisant office d'alternative textuelle et un autre faisant office de description détaillée ; Il existe un attribut WAI-ARIA aria-describedby associant un passage de texte faisant office de description détaillée ; Il existe un lien ou un bouton adjacent permettant d'accéder à la description détaillée.

Démo volontairement fautive

Voir le code source du piège
<svg role="img" width="160" height="100" aria-label="Ventes par trimestre"><rect width="50" height="60" x="5" fill="#33f"></rect><rect width="50" height="90" x="60" fill="#f33"></rect></svg>

Ce qui ne va pas : L'image vectorielle complexe n'a qu'un aria-label court : aucune description détaillée (aria-describedby, <desc> ou lien adjacent) ne restitue les valeurs.

Comment corriger : Associer une description détaillée via aria-describedby ou ajouter un lien adjacent vers un tableau de données.

WCAG :
  • 1.1.1 Non-text Content (A)

1.6.6 manuel

Pour chaque image vectorielle (balise <svg>) porteuse d'information, ayant une description détaillée, la référence éventuelle à la description détaillée dans l'attribut WAI-ARIA aria-label et la description détaillée associée par l'attribut WAI-ARIA aria-labelledby ou aria-describedby sont-elles correctement restituées par les technologies d'assistance ?

Démo volontairement fautive

Données détaillées
Voir le code source du piège
<svg role="img" aria-label="Ventes par trimestre (voir description)" width="160" height="100"><desc>Données détaillées</desc><rect width="50" height="60" x="5" fill="#33f"></rect></svg>

Ce qui ne va pas : La référence à la description détaillée placée dans aria-label et la description associée via <desc> ne sont pas restituées de façon fiable par toutes les technologies d'assistance.

Comment corriger : Tester la restitution avec des lecteurs d'écran ; préférer aria-describedby vers un passage de texte visible. Vérification manuelle.

WCAG :
  • 1.1.1 Non-text Content (A)

1.6.7 manuel

Chaque image bitmap (balise <canvas>), porteuse d'information, qui nécessite une description détaillée, vérifie-t-elle une de ces conditions ? Il existe un attribut WAI-ARIA aria-label contenant l'alternative textuelle et une référence à une description détaillée adjacente ; Il existe un attribut WAI-ARIA aria-labelledby associant un passage de texte faisant office d'alternative textuelle et un autre faisant office de description détaillée ; Il existe un contenu textuel entre <canvas> et </canvas> faisant référence à une description détaillée adjacente à l'image bitmap ; Il existe un contenu textuel entre <canvas> et </canvas> faisant office de description détaillée ; Il existe un lien ou bouton adjacent permettant d'accéder à la description détaillée.

Démo volontairement fautive

Voir le code source du piège
<canvas role="img" aria-label="Ventes par trimestre" width="160" height="100"></canvas>

Ce qui ne va pas : L'image bitmap complexe n'a qu'une alternative courte ; aucune description détaillée (texte interne, lien adjacent…) n'est fournie.

Comment corriger : Ajouter un contenu textuel de remplacement avec référence à une description détaillée, ou un lien adjacent vers les données.

WCAG :
  • 1.1.1 Non-text Content (A)

1.6.8 manuel

Pour chaque image bitmap (balise <canvas>) porteuse d'information, qui implémente une référence à une description détaillée adjacente, cette référence est-elle correctement restituée par les technologies d'assistance ?

Démo volontairement fautive

Voir la description du graphique plus bas
Voir le code source du piège
<canvas role="img" aria-label="Ventes par trimestre (description ci-dessous)" width="160" height="100">Voir la description du graphique plus bas</canvas>

Ce qui ne va pas : La référence à la description détaillée implémentée dans le <canvas> n'est pas correctement restituée : le contenu interne des <canvas> est ignoré par la plupart des technologies d'assistance.

Comment corriger : Placer la référence hors de la balise (lien adjacent visible) ou utiliser aria-describedby. Test manuel avec lecteur d'écran.

WCAG :
  • 1.1.1 Non-text Content (A)

1.6.9 partiel

Pour chaque image (balise <img>, <input> avec l'attribut type="image", <area>, <object>, <embed>, <svg>, <canvas>, ou possédant un attribut WAI-ARIA role="img") porteuse d'information, qui est accompagnée d'une description détaillée et qui utilise un attribut WAI-ARIA aria-describedby, l'attribut WAI-ARIA aria-describedby associe-t-il la description détaillée ?

Démo volontairement fautive

Ventes par trimestre
Voir le code source du piège
<img src="img/chart.png" alt="Ventes par trimestre" aria-describedby="f-1-6-9-desc" width="160" height="100">

Ce qui ne va pas : L'attribut aria-describedby référence un identifiant (f-1-6-9-desc) qui n'existe nulle part dans la page : aucune description détaillée n'est réellement associée. axe-core signale ce cas en incomplete : la vérification humaine est nécessaire.

Comment corriger : Créer le passage de texte référencé (ex. <p id="f-1-6-9-desc">Tableau des ventes…</p>) ou retirer l'attribut.

WCAG :
  • 1.1.1 Non-text Content (A)

1.6.10 manuel

Chaque balise possédant un attribut WAI-ARIA role="img" porteuse d'information, qui nécessite une description détaillée, vérifie-t-elle une de ces conditions ? Il existe un attribut WAI-ARIA aria-label contenant l'alternative textuelle et une référence à une description détaillée adjacente ; Il existe un attribut WAI-ARIA aria-labelledby associant un passage de texte faisant office d'alternative textuelle et un autre faisant office de description détaillée ; Il existe un attribut WAI-ARIA aria-describedby associant un passage de texte faisant office de description détaillée ; Il existe un lien ou un bouton adjacent permettant d'accéder à la description détaillée.

Démo volontairement fautive

Graphique des ventes
Voir le code source du piège
<div role="img" aria-label="Ventes par trimestre">Graphique des ventes</div>

Ce qui ne va pas : L'élément avec role="img" est porteur d'un graphique complexe mais n'a pas de description détaillée (aria-describedby ou lien adjacent).

Comment corriger : Associer une description détaillée via aria-describedby ou ajouter un lien adjacent vers les données. Vérification manuelle.

WCAG :
  • 1.1.1 Non-text Content (A)

1.7 — Pour chaque image porteuse d'information ayant une description détaillée, cette description est-elle pertinente ?

1.7.1 manuel

Chaque image (balise <img>) porteuse d'information, ayant une description détaillée, vérifie-t-elle ces conditions ? La description détaillée via l'adresse référencée dans l'attribut longdesc est pertinente ; La description détaillée dans la page et signalée par l'alternative textuelle est pertinente ; La description détaillée via un lien ou bouton adjacent est pertinente ; Le passage de texte associé via l'attribut WAI-ARIA aria-describedby est pertinent.

Démo volontairement fautive

Ventes par trimestre (description)
Voir le code source du piège
<img src="img/chart.png" alt="Ventes par trimestre (description)" longdesc="desc.html" width="160" height="100">

Ce qui ne va pas : La description détaillée pointée par longdesc (ou le lien adjacent) est absente ou ne décrit pas réellement le graphique : elle n'est pas pertinente.

Comment corriger : Rédiger une description qui restitue toutes les données essentielles (valeurs, axes, tendance). La pertinence s'évalue manuellement.

WCAG :
  • 1.1.1 Non-text Content (A)

1.7.2 manuel

Chaque bouton de type image (balise <input> avec l'attribut type="image") porteur d'information, ayant une description détaillée, vérifie-t-elle ces conditions ? La description détaillée dans la page et signalée par l'alternative textuelle est pertinente ; La description détaillée via un lien ou bouton adjacent est pertinente ; Le passage de texte associé via l'attribut WAI-ARIA aria-describedby est pertinent.

Démo volontairement fautive

Description

Voir le code source du piège
<input type="image" src="img/chart.png" alt="Ventes (description)" aria-describedby="f-1-7-2-desc" width="160" height="100"><p id="f-1-7-2-desc">Description</p>

Ce qui ne va pas : La description associée via aria-describedby se limite au mot « Description » : elle ne restitue aucune donnée du graphique.

Comment corriger : Rédiger une description détaillée complète et pertinente. Vérification manuelle.

WCAG :
  • 1.1.1 Non-text Content (A)

1.7.3 manuel

Chaque image objet (balise <object> avec l'attribut type="image/…") porteuse d'information, ayant une description détaillée, vérifie-t-elle ces conditions ? La description détaillée dans la page et signalée par l'alternative textuelle est pertinente ; La description détaillée adjacente à l'image objet est pertinente ; La description détaillée via un lien ou bouton adjacent est pertinente ; Le passage de texte associé via l'attribut WAI-ARIA aria-describedby est pertinent.

Démo volontairement fautive

Graphique (voir plus bas)

Suite du texte

Voir le code source du piège
<object type="image/png" data="img/chart.png" width="160" height="100">Graphique (voir plus bas)</object><p>Suite du texte</p>

Ce qui ne va pas : L'alternative annonce une description « plus bas » qui n'existe pas : la description détaillée signalée n'est pas pertinente.

Comment corriger : Placer une description réelle et complète à l'endroit signalé, ou retirer la référence. Vérification manuelle.

WCAG :
  • 1.1.1 Non-text Content (A)

1.7.4 manuel

Chaque image embarquée (balise <embed> avec l'attribut type="image/…") porteuse d'information, ayant une description détaillée, vérifie-t-elle ces conditions ? La description détaillée dans la page et signalée par l'alternative textuelle est pertinente ; La description détaillée adjacente à l'image embarquée est pertinente ; La description détaillée via un lien ou bouton adjacent est pertinente ; Le passage de texte associé via l'attribut WAI-ARIA aria-describedby est pertinent.

Démo volontairement fautive

Voir le code source du piège
<embed type="image/png" src="img/chart.png" aria-label="Ventes par trimestre (détails ci-contre)" width="160" height="100">

Ce qui ne va pas : La description annoncée « ci-contre » est absente : la référence est mensongère et la description détaillée non pertinente.

Comment corriger : Fournir la description au lieu annoncé ou adjoindre un lien adjacent vers un tableau de données. Vérification manuelle.

WCAG :
  • 1.1.1 Non-text Content (A)

1.7.5 manuel

Chaque image vectorielle (balise <svg>) porteuse d'information, ayant une description détaillée, vérifie-t-elle ces conditions ? La description détaillée dans la page et signalée par l'alternative textuelle est pertinente ; La description détaillée dans la page et signalée par le texte contenu dans balise <desc> ou <title> est pertinente ; La description détaillée contenue dans la balise <desc> est pertinente ; La description détaillée via un lien ou bouton adjacent est pertinente ; Le passage de texte associé via l'attribut WAI-ARIA aria-describedby est pertinent.

Démo volontairement fautive

Ventesdonnées
Voir le code source du piège
<svg role="img" width="160" height="100"><title>Ventes</title><desc>données</desc><rect width="50" height="60" x="5" fill="#33f"></rect><rect width="50" height="90" x="60" fill="#f33"></rect></svg>

Ce qui ne va pas : La description contenue dans <desc> (« données ») ne décrit pas réellement le graphique : elle n'est pas pertinente.

Comment corriger : Décrire précisément les valeurs et la tendance dans <desc>, ou associer une description via aria-describedby. Vérification manuelle.

WCAG :
  • 1.1.1 Non-text Content (A)

1.7.6 manuel

Chaque image bitmap (balise <canvas>) porteuse d'information, ayant une description détaillée, vérifie-t-elle ces conditions ? La description détaillée dans la page et signalée par l'alternative textuelle est pertinente ; La description détaillée dans la page et signalée par le texte contenu entre <canvas> et </canvas> est pertinente ; La description détaillée contenue entre <canvas> et </canvas> est pertinente ; La description détaillée adjacente à l'image bitmap est pertinente ; La description détaillée via un lien ou bouton adjacent est pertinente ; Le passage de texte associé via l'attribut WAI-ARIA aria-describedby est pertinent.

Démo volontairement fautive

voir plus bas

Le graphique montre des ventes.

Voir le code source du piège
<canvas role="img" aria-label="Ventes" width="160" height="100">voir plus bas</canvas><p>Le graphique montre des ventes.</p>

Ce qui ne va pas : La description détaillée signalée (« voir plus bas ») renvoie à un texte vague qui ne restitue aucune donnée : elle n'est pas pertinente.

Comment corriger : Rédiger une description complète (valeurs, axes, tendance) au lieu annoncé. Vérification manuelle.

WCAG :
  • 1.1.1 Non-text Content (A)

1.8 — Chaque image texte porteuse d'information, en l'absence d'un mécanisme de remplacement, doit si possible être remplacée par du texte stylé. Cette règle est-elle respectée (hors cas particuliers) ?

1.8.1 manuel

Chaque image texte (balise <img> ou possédant un attribut WAI-ARIA role="img") porteuse d'information, en l'absence d'un mécanisme de remplacement, doit si possible être remplacée par du texte stylé. Cette règle est-elle respectée (hors cas particuliers) ?

Démo volontairement fautive

Bienvenue
Voir le code source du piège
<img src="img/info.png" alt="Bienvenue" width="120" height="80">

Ce qui ne va pas : L'information est présentée sous forme d'image texte alors qu'elle aurait pu être rédigée en texte stylé (CSS). Sans mécanisme de remplacement, le texte ne peut pas être adapté (zoom, police, contraste).

Comment corriger : Remplacer par du texte réel stylé : <p class="titre">Bienvenue</p> avec les styles CSS correspondants. La décision relève d'un jugement humain.

WCAG :
  • 1.4.5 Images of Text (AA)

1.8.2 manuel

Chaque bouton « image texte » (balise <input> avec l'attribut type="image") porteur d'information, en l'absence d'un mécanisme de remplacement, doit si possible être remplacé par du texte stylé. Cette règle est-elle respectée (hors cas particuliers) ?

Démo volontairement fautive

Voir le code source du piège
<input type="image" src="img/logo.png" alt="Valider" width="100" height="40">

Ce qui ne va pas : Le bouton est une image texte : son libellé est figé dans l'image et ne peut pas être adapté par l'utilisateur (police, zoom, contraste).

Comment corriger : Remplacer par un bouton texte stylé : <button type="submit">Valider</button>. Vérification manuelle.

WCAG :
  • 1.4.5 Images of Text (AA)

1.8.3 manuel

Chaque image texte objet (balise <object> avec l'attribut type="image/…") porteuse d'information, en l'absence d'un mécanisme de remplacement, doit si possible être remplacée par du texte stylé. Cette règle est-elle respectée (hors cas particuliers) ?

Démo volontairement fautive

Bienvenue
Voir le code source du piège
<object type="image/png" data="img/info.png" width="120" height="80">Bienvenue</object>

Ce qui ne va pas : Le texte « Bienvenue » est fourni en image objet : sans mécanisme de remplacement, il ne peut pas être stylé ni adapté par l'utilisateur.

Comment corriger : Remplacer par du texte stylé (CSS). Vérification manuelle.

WCAG :
  • 1.4.5 Images of Text (AA)

1.8.4 manuel

Chaque image texte embarquée (balise <embed> avec l'attribut type="image/…") porteuse d'information, en l'absence d'un mécanisme de remplacement, doit si possible être remplacée par du texte stylé. Cette règle est-elle respectée (hors cas particuliers) ?

Démo volontairement fautive

Voir le code source du piège
<embed type="image/png" src="img/info.png" aria-label="Bienvenue" width="120" height="80">

Ce qui ne va pas : Le texte est embarqué en image : il ne suit ni la police ni les réglages de l'utilisateur.

Comment corriger : Remplacer par du texte réel stylé. Vérification manuelle.

WCAG :
  • 1.4.5 Images of Text (AA)

1.8.5 manuel

Chaque image texte bitmap (balise <canvas>) porteuse d'information, en l'absence d'un mécanisme de remplacement, doit si possible être remplacée par du texte stylé. Cette règle est-elle respectée (hors cas particuliers) ?

Démo volontairement fautive

Bienvenue
Voir le code source du piège
<canvas role="img" aria-label="Bienvenue" width="120" height="80">Bienvenue</canvas>

Ce qui ne va pas : Le texte est dessiné dans un <canvas> : il n'est pas sélectionnable et ne s'adapte pas aux préférences de l'utilisateur.

Comment corriger : Remplacer par du texte stylé. Vérification manuelle.

WCAG :
  • 1.4.5 Images of Text (AA)

1.8.6 manuel

Chaque image texte SVG (balise <svg>) porteuse d'information et dont le texte n'est pas complètement structuré au moyen d'éléments <text>, en l'absence d'un mécanisme de remplacement, doit si possible être remplacée par du texte stylé. Cette règle est-elle respectée (hors cas particuliers) ?

Démo volontairement fautive

Voir le code source du piège
<svg role="img" width="120" height="40" aria-label="Bienvenue"><path d="M5 30 L10 10 L15 30 L20 10 L25 30"></path></svg>

Ce qui ne va pas : Le texte « Bienvenue » est dessiné en SVG avec des chemins (<path>) au lieu d'éléments <text> : il n'est pas structuré et ne peut pas être lu ni adapté.

Comment corriger : Utiliser des éléments <text> réels dans le SVG, ou remplacer par du texte HTML stylé. Vérification manuelle.

WCAG :
  • 1.4.5 Images of Text (AA)

1.9 — Chaque légende d'image est-elle, si nécessaire, correctement reliée à l'image correspondante ?

1.9.1 manuel

Chaque image pourvue d'une légende (balise <img>, <input> avec l'attribut type="image" ou possédant un attribut WAI-ARIA role="img" associée à une légende adjacente), vérifie-t-elle, si nécessaire, ces conditions ? L'image (balise <img>, <input> avec l'attribut type="image" ou possédant un attribut WAI-ARIA role="img") et sa légende adjacente sont contenues dans une balise <figure> ; La balise <figure> possède un attribut WAI-ARIA role="figure" ou role="group" ; La balise <figure> possède un attribut WAI-ARIA aria-label dont le contenu est identique au contenu de la légende ; La légende est contenue dans une balise <figcaption>.

Démo volontairement fautive

Ventes par trimestre

Ventes 2024

Voir le code source du piège
<img src="img/chart.png" alt="Ventes par trimestre" width="160" height="100"><p>Ventes 2024</p>

Ce qui ne va pas : La légende « Ventes 2024 » est visuellement adjacente à l'image mais aucun lien structurel (<figure>/<figcaption>) ne les associe.

Comment corriger : Encapsuler image et légende : <figure role="group" aria-label="Ventes 2024"><img …><figcaption>Ventes 2024</figcaption></figure>.

WCAG :
  • 1.1.1 Non-text Content (A)
  • 4.1.2 Name, Role, Value (A)

1.9.2 manuel

Chaque image objet pourvue d'une légende (balise <object> avec l'attribut type="image/…" associée à une légende adjacente), vérifie-t-elle, si nécessaire, ces conditions ? L'image objet (balise <object>) et sa légende adjacente sont contenues dans une balise <figure> ; La balise <figure> possède un attribut WAI-ARIA role="figure" ou role="group" ; La balise <figure> possède un attribut WAI-ARIA aria-label dont le contenu est identique au contenu de la légende ; La légende est contenue dans une balise <figcaption>.

Démo volontairement fautive

Ventes par trimestre

Ventes 2024

Voir le code source du piège
<object type="image/png" data="img/chart.png" width="160" height="100">Ventes par trimestre</object><p>Ventes 2024</p>

Ce qui ne va pas : La légende de l'image objet n'est pas associée structurellement à l'image (pas de <figure>/<figcaption>).

Comment corriger : Regrouper dans <figure role="figure" aria-label="Ventes 2024"> avec <figcaption>. Vérification manuelle.

WCAG :
  • 1.1.1 Non-text Content (A)
  • 4.1.2 Name, Role, Value (A)

1.9.3 manuel

Chaque image embarquée pourvue d'une légende (balise <embed> associée à une légende adjacente), vérifie-t-elle, si nécessaire, ces conditions ? L'image embarquée (balise <embed>) et sa légende adjacente sont contenues dans une balise <figure> ; La balise <figure> possède un attribut WAI-ARIA role="figure" ou role="group" ; La balise <figure> possède un attribut WAI-ARIA aria-label dont le contenu est identique au contenu de la légende ; La légende est contenue dans une balise <figcaption>.

Démo volontairement fautive

Ventes 2024

Voir le code source du piège
<embed type="image/png" src="img/chart.png" aria-label="Ventes par trimestre" width="160" height="100"><p>Ventes 2024</p>

Ce qui ne va pas : La légende adjacente à l'image embarquée n'est reliée par aucune structure (<figure>/<figcaption>).

Comment corriger : Encapsuler l'image et sa légende dans <figure> avec <figcaption>. Vérification manuelle.

WCAG :
  • 1.1.1 Non-text Content (A)
  • 4.1.2 Name, Role, Value (A)

1.9.4 manuel

Chaque image vectorielle pourvue d'une légende (balise <svg> associée à une légende adjacente), vérifie-t-elle, si nécessaire, ces conditions ? L'image vectorielle (balise <svg>) et sa légende adjacente sont contenues dans une balise <figure> ; La balise <figure> possède un attribut WAI-ARIA role="figure" ou role="group" ; La balise <figure> possède un attribut WAI-ARIA aria-label dont le contenu est identique au contenu de la légende ; La légende est contenue dans une balise <figcaption>.

Démo volontairement fautive

Ventes 2024

Voir le code source du piège
<svg role="img" width="160" height="100" aria-label="Ventes par trimestre"><rect width="50" height="60" x="5" fill="#33f"></rect></svg><p>Ventes 2024</p>

Ce qui ne va pas : La légende « Ventes 2024 » n'est pas reliée à l'image vectorielle : aucun <figure>/<figcaption> ne les groupe.

Comment corriger : Utiliser <figure role="group" aria-label="Ventes 2024"> contenant le <svg> et un <figcaption>. Vérification manuelle.

WCAG :
  • 1.1.1 Non-text Content (A)
  • 4.1.2 Name, Role, Value (A)

1.9.5 manuel

Chaque image bitmap pourvue d'une légende (balise <canvas> associée à une légende adjacente), vérifie-t-elle, si nécessaire, ces conditions ? L'image bitmap (balise <canvas>) et sa légende adjacente sont contenues dans une balise <figure> ; La balise <figure> possède un attribut WAI-ARIA role="figure" ou role="group" ; La balise <figure> possède un attribut WAI-ARIA aria-label dont le contenu est identique au contenu de la légende ; La légende est contenue dans une balise <figcaption>.

Démo volontairement fautive

Ventes 2024

Voir le code source du piège
<canvas role="img" aria-label="Ventes par trimestre" width="160" height="100"></canvas><p>Ventes 2024</p>

Ce qui ne va pas : La légende adjacente au <canvas> n'est associée à l'image par aucune structure (<figure>/<figcaption>).

Comment corriger : Regrouper dans <figure> avec <figcaption>. Vérification manuelle.

WCAG :
  • 1.1.1 Non-text Content (A)
  • 4.1.2 Name, Role, Value (A)

2. Cadres (2 tests)

Chaque cadre (iframe, frame) doit être titré pour être identifiable par les technologies d'assistance.

2.1 — Chaque cadre a-t-il un titre de cadre ?

2.1.1 axe · frame-title

Chaque cadre (balise <iframe> ou <frame>) a-t-il un attribut title ?

Démo volontairement fautive

Voir le code source du piège
<iframe src="page2.html" width="300" height="200"></iframe>

Ce qui ne va pas : Le cadre n'a pas d'attribut title : un utilisateur de lecteur d'écran ne peut pas savoir ce que contient ce cadre ni l'identifier dans la liste des cadres.

Comment corriger : Ajouter un title descriptif : <iframe src="page2.html" title="Formulaire de contact" width="300" height="200"></iframe>.

WCAG :
  • 4.1.2 Name, Role, Value (A)

2.2 — Pour chaque cadre ayant un titre de cadre, ce titre de cadre est-il pertinent ?

2.2.1 manuel

Pour chaque cadre (balise <iframe> ou <frame>) ayant un attribut title, le contenu de cet attribut est-il pertinent ?

Démo volontairement fautive

Voir le code source du piège
<iframe src="page2.html" title="contenu" width="300" height="200"></iframe>

Ce qui ne va pas : Le titre « contenu » est générique : il n'identifie pas le rôle du cadre (ex. « Plan du site »). Un utilisateur ne peut pas choisir de l'ouvrir ou de l'ignorer.

Comment corriger : Donner un titre spécifique et pertinent, ex. title="Liste des actualités". La pertinence s'évalue manuellement (axe ne vérifie que la présence d'un titre non vide).

WCAG :
  • 4.1.2 Name, Role, Value (A)

3. Couleurs (15 tests)

La couleur ne doit jamais être le seul vecteur d'information : contraste, usage de la couleur seule, et signalement des liens.

3.1 — Dans chaque page web, l'information ne doit pas être donnée uniquement par la couleur. Cette règle est-elle respectée ?

3.1.1 manuel

Pour chaque mot ou ensemble de mots dont la mise en couleur est porteuse d'information, l'information ne doit pas être donnée uniquement par la couleur. Cette règle est-elle respectée ?

Démo volontairement fautive

Les champs en rouge sont obligatoires.

Voir le code source du piège
<p>Les champs en <span style="color:#c00">rouge</span> sont obligatoires.</p>

Ce qui ne va pas : L'information « obligatoire » n'est transmise que par la couleur rouge des mots. Une personne daltonienne ou un utilisateur de lecteur d'écran ne peut pas la percevoir.

Comment corriger : Ajouter un marqueur non chromatique (ex. « (obligatoire) ») en plus de la couleur. Aucune règle axe ne juge ce cas : vérification manuelle.

WCAG :
  • 1.3.1 Info and Relationships (A)
  • 1.4.1 Use of color (A)

3.1.2 manuel

Pour chaque indication de couleur donnée par un texte, l'information ne doit pas être donnée uniquement par la couleur. Cette règle est-elle respectée ?

Démo volontairement fautive

Erreur : adresse invalide.

Voir le code source du piège
<p style="color:#c00">Erreur : adresse invalide.</p>

Ce qui ne va pas : L'information « erreur » n'est donnée que par la couleur du texte : sans elle, rien ne distingue ce message des autres.

Comment corriger : Ajouter un pictogramme, un préfixe texte (ex. « Erreur : ») ou un attribut role="alert" en complément de la couleur. Vérification manuelle.

WCAG :
  • 1.3.1 Info and Relationships (A)
  • 1.4.1 Use of color (A)

3.1.3 manuel

Pour chaque image véhiculant une information, l'information ne doit pas être donnée uniquement par la couleur. Cette règle est-elle respectée ?

Démo volontairement fautive

Répartition des ventes
Voir le code source du piège
<img src="img/chart.png" alt="Répartition des ventes" width="160" height="100">

Ce qui ne va pas : Le graphique ne distingue ses séries que par la couleur des barres : une personne daltonienne ne peut pas les différencier ni lire l'information.

Comment corriger : Ajouter des motifs, des étiquettes ou une légende textuelle en complément des couleurs, et le préciser dans l'alternative. Vérification manuelle.

WCAG :
  • 1.3.1 Info and Relationships (A)
  • 1.4.1 Use of color (A)

3.1.4 manuel

Pour chaque propriété CSS déterminant une couleur et véhiculant une information, l'information ne doit pas être donnée uniquement par la couleur. Cette règle est-elle respectée ?

Démo volontairement fautive

Votre commande a bien été enregistrée.

Voir le code source du piège
<p style="background-color:#0a0">Votre commande a bien été enregistrée.</p>

Ce qui ne va pas : L'information « succès » n'est transmise que par la couleur de fond verte de la propriété CSS : elle est invisible pour une personne daltonienne.

Comment corriger : Ajouter un texte ou une icône signifiant le succès en plus de la couleur de fond. Vérification manuelle.

WCAG :
  • 1.3.1 Info and Relationships (A)
  • 1.4.1 Use of color (A)

3.1.5 manuel

Pour chaque média temporel véhiculant une information, l'information ne doit pas être donnée uniquement par la couleur. Cette règle est-elle respectée ?

Démo volontairement fautive

Voir le code source du piège
<video src="media/video.mp4" controls width="320" height="240"></video>

Ce qui ne va pas : Le média temporel transmet une partie de son information par la seule couleur (ex. feu rouge/vert) : elle est inaccessible aux daltoniens.

Comment corriger : Doubler l'information par du texte, un symbole ou une annotation audio. L'analyse du contenu du média est manuelle.

WCAG :
  • 1.3.1 Info and Relationships (A)
  • 1.4.1 Use of color (A)

3.1.6 manuel

Pour chaque média non temporel véhiculant une information, l'information ne doit pas être donnée uniquement par la couleur. Cette règle est-elle respectée ?

Démo volontairement fautive

Répartition des ventes
Voir le code source du piège
<object type="image/png" data="img/chart.png" width="160" height="100">Répartition des ventes</object>

Ce qui ne va pas : Le média non temporel (graphique) véhicule une information donnée uniquement par la couleur des zones.

Comment corriger : Ajouter des motifs ou étiquettes différenciant les zones, et décrire l'information dans l'alternative. Vérification manuelle.

WCAG :
  • 1.3.1 Info and Relationships (A)
  • 1.4.1 Use of color (A)

3.2 — Dans chaque page web, le contraste entre la couleur du texte et la couleur de son arrière-plan est-il suffisamment élevé (hors cas particuliers) ?

3.2.1 axe · color-contrast

Dans chaque page web, le texte et le texte en image sans effet de graisse d'une taille restituée inférieure à 24px vérifient-ils une de ces conditions (hors cas particuliers) ? Le rapport de contraste entre le texte et son arrière-plan est de 4.5:1, au moins ; Un mécanisme permet à l'utilisateur d'afficher le texte avec un rapport de contraste de 4.5:1, au moins.

Démo volontairement fautive

Ce texte est difficile à lire.

Voir le code source du piège
<p style="color:#9a9a9a">Ce texte est difficile à lire.</p>

Ce qui ne va pas : Le texte gris clair sur fond blanc affiche un rapport de contraste d'environ 2,8:1, très inférieur au seuil de 4,5:1 exigé pour un texte de taille normale.

Comment corriger : Choisir une couleur plus sombre (ex. #595959) pour atteindre au moins 4,5:1, ou proposer un mécanisme de contraste conforme.

WCAG :
  • 1.4.3 Contrast (Minimum) (AA)

3.2.2 axe · color-contrast

Dans chaque page web, le texte et le texte en image en gras d'une taille restituée inférieure à 18,5px vérifient-ils une de ces conditions (hors cas particuliers) ? Le rapport de contraste entre le texte et son arrière-plan est de 4.5:1, au moins ; Un mécanisme permet à l'utilisateur d'afficher le texte avec un rapport de contraste de 4.5:1, au moins.

Démo volontairement fautive

Texte en gras peu lisible.

Voir le code source du piège
<p style="color:#9a9a9a;font-weight:bold">Texte en gras peu lisible.</p>

Ce qui ne va pas : Le texte gras de taille normale a un contraste d'environ 2,8:1, sous le seuil de 4,5:1 (le seuil de 3:1 ne s'applique qu'aux grands textes, ≥ 18,5px en gras).

Comment corriger : Assombrir la couleur du texte ou alléger l'arrière-plan pour dépasser 4,5:1.

WCAG :
  • 1.4.3 Contrast (Minimum) (AA)

3.2.3 axe · color-contrast

Dans chaque page web, le texte et le texte en image sans effet de graisse d'une taille restituée supérieure ou égale à 24px vérifient-ils une de ces conditions (hors cas particuliers) ? Le rapport de contraste entre le texte et son arrière-plan est de 3:1, au moins ; Un mécanisme permet à l'utilisateur d'afficher le texte avec un rapport de contraste de 3:1, au moins.

Démo volontairement fautive

Grand titre peu contrasté.

Voir le code source du piège
<p style="color:#b3b3b3;font-size:24px">Grand titre peu contrasté.</p>

Ce qui ne va pas : Pour un grand texte (≥ 24px), le seuil exigé est de 3:1 : ici le contraste n'atteint qu'environ 2,1:1.

Comment corriger : Assombrir la couleur (ex. #767676) pour atteindre au moins 3:1.

WCAG :
  • 1.4.3 Contrast (Minimum) (AA)

3.2.4 axe · color-contrast

Dans chaque page web, le texte et le texte en image en gras d'une taille restituée supérieure ou égale à 18,5px vérifient-ils une de ces conditions (hors cas particuliers) ? Le rapport de contraste entre le texte et son arrière-plan est de 3:1, au moins ; Un mécanisme permet à l'utilisateur d'afficher le texte avec un rapport de contraste de 3:1, au moins.

Démo volontairement fautive

Titre en gras peu contrasté.

Voir le code source du piège
<p style="color:#b3b3b3;font-size:19px;font-weight:bold">Titre en gras peu contrasté.</p>

Ce qui ne va pas : Un texte gras de 19px est considéré comme « grand texte » : le seuil est de 3:1, or le contraste affiché n'est que d'environ 2,1:1.

Comment corriger : Assombrir la couleur du texte pour atteindre au moins 3:1.

WCAG :
  • 1.4.3 Contrast (Minimum) (AA)

3.2.5 n/a

Dans le mécanisme qui permet d'afficher un rapport de contraste conforme, le rapport de contraste entre le texte et la couleur d’arrière-plan est-il suffisamment élevé ?

Démo volontairement fautive

Non démontrable en page statique — voir l'explication ci-dessous.

Ce qui ne va pas : Ce test ne s'applique qu'en présence d'un mécanisme permettant d'afficher un rapport de contraste conforme. Un tel mécanisme (feuille de style alternative, réglage JavaScript) suppose une interaction et un comportement dynamique non démontrables dans une page statique.

Comment corriger : En conditions réelles, vérifier que le mécanisme affiche bien un texte dont le contraste atteint le seuil exigé (4,5:1 ou 3:1 selon la taille).

WCAG :
  • 1.4.3 Contrast (Minimum) (AA)

3.3 — Dans chaque page web, les couleurs utilisées dans les composants d'interface ou les éléments graphiques porteurs d'informations sont-elles suffisamment contrastées (hors cas particuliers) ?

3.3.1 manuel

Dans chaque page web, le rapport de contraste entre les couleurs d'un composant d'interface dans ses différents états et la couleur d'arrière-plan contiguë vérifie-t-il une de ces conditions (hors cas particuliers) ? Le rapport de contraste est de 3:1, au moins ; Un mécanisme permet un rapport de contraste de 3:1, au moins.

Démo volontairement fautive

Voir le code source du piège
<p><input type="text" placeholder="Nom" style="border:1px solid #e0e0e0"></p>

Ce qui ne va pas : La bordure du champ (gris très clair sur fond blanc) est la seule indication visuelle du composant : son contraste d'environ 1,4:1 est très inférieur au seuil de 3:1 exigé pour les composants d'interface. La règle color-contrast d'axe ne mesure que le contraste des textes : ce contrôle est donc manuel.

Comment corriger : Assombrir la bordure (ex. #767676) ou renforcer l'état visuel du champ pour atteindre 3:1. axe la détecte via color-contrast (non-text contrast).

WCAG :
  • 1.4.11 Non-text Contrast (AA)

3.3.2 manuel

Dans chaque page web, le rapport de contraste des différentes couleurs composant un élément graphique, lorsqu'elles sont nécessaires à sa compréhension, et la couleur d'arrière-plan contiguë, vérifie-t-il une de ces conditions (hors cas particuliers) ? Le rapport de contraste est de 3:1, au moins ; Un mécanisme permet un rapport de contraste de 3:1, au moins.

Démo volontairement fautive

Ventes par trimestre
Voir le code source du piège
<img src="img/chart.png" alt="Ventes par trimestre" width="160" height="100">

Ce qui ne va pas : Les couleurs du graphique, nécessaires à sa compréhension, ne présentent pas un contraste suffisant (3:1) avec l'arrière-plan contigu. axe ne peut pas analyser le contenu d'une image bitmap.

Comment corriger : Renforcer le contraste des couleurs du graphique ou ajouter des motifs/étiquettes. La mesure se fait avec un outil de contraste sur les couleurs réelles (manuel).

WCAG :
  • 1.4.11 Non-text Contrast (AA)

3.3.3 manuel

Dans chaque page web, le rapport de contraste des différentes couleurs contiguës entre elles d'un élément graphique, lorsqu'elles sont nécessaires à sa compréhension, vérifie-t-il une de ces conditions (hors cas particuliers) ? Le rapport de contraste est de 3:1, au moins ; Un mécanisme permet un rapport de contraste de 3:1, au moins.

Démo volontairement fautive

Voir le code source du piège
<svg width="80" height="40"><rect width="40" height="40" fill="#e8e8e8"></rect><rect x="40" width="40" height="40" fill="#f5f5f5"></rect></svg>

Ce qui ne va pas : Les deux zones contiguës du graphique ne se distinguent que par des gris très proches : le contraste entre elles est inférieur à 3:1 alors qu'il est nécessaire à la compréhension.

Comment corriger : Augmenter l'écart de luminance entre les zones contiguës (≥ 3:1) ou les différencier par un motif. Vérification manuelle.

WCAG :
  • 1.4.11 Non-text Contrast (AA)

3.3.4 n/a

Dans le mécanisme qui permet d'afficher un rapport de contraste conforme, les couleurs du composant ou des éléments graphiques porteurs d’informations qui le composent, sont-elles suffisamment contrastées ?

Démo volontairement fautive

Non démontrable en page statique — voir l'explication ci-dessous.

Ce qui ne va pas : Ce test ne s'applique qu'en présence d'un mécanisme permettant d'afficher des composants suffisamment contrastés. Son fonctionnement (changement de thème, CSS alternatif) nécessite une interaction non démontrable dans une page statique.

Comment corriger : En conditions réelles, vérifier que le mécanisme affiche des composants et éléments graphiques avec un contraste d'au moins 3:1.

WCAG :
  • 1.4.11 Non-text Contrast (AA)

4. Multimédia (25 tests)

Les médias temporels (audio, vidéo) et non temporels doivent proposer transcriptions, sous-titres, audiodescriptions et contrôles accessibles.

4.1 — Chaque média temporel pré-enregistré a-t-il, si nécessaire, une transcription textuelle ou une audiodescription (hors cas particuliers) ?

4.1.1 manuel

Chaque média temporel pré-enregistré seulement audio, vérifie-t-il, si nécessaire, l'une de ces conditions (hors cas particuliers) ? Il existe une transcription textuelle accessible via un lien ou bouton adjacent ; Il existe une transcription textuelle adjacente clairement identifiable.

Démo volontairement fautive

Voir le code source du piège
<audio src="media/audio.mp3" controls></audio>

Ce qui ne va pas : Ce média temporel pré-enregistré seulement audio ne propose aucune transcription textuelle : ni texte adjacent clairement identifiable, ni lien ou bouton adjacent y menant. Une personne sourde ou malentendante n'a donc aucun accès au contenu sonore.

Comment corriger : Ajouter à côté du lecteur une transcription textuelle complète du contenu parlé et des informations sonores. Un lien adjacent « Transcription » qui y mène est également acceptable.

WCAG :
  • 1.2.1 Audio-only and Video-only (Prerecorded) (A)
  • 1.2.3 Audio Description or Media Alternative (Prerecorded) (A)

4.1.2 manuel

Chaque média temporel pré-enregistré seulement vidéo vérifie-t-il, si nécessaire, l'une de ces conditions (hors cas particuliers) ? Il existe une version alternative « audio seulement » accessible via un lien ou bouton adjacent ; Il existe une version alternative « audio seulement » adjacente clairement identifiable ; Il existe une transcription textuelle accessible via un lien ou bouton adjacent ; Il existe une transcription textuelle adjacente clairement identifiable ; Il existe une audiodescription synchronisée ; Il existe une version alternative avec une audiodescription synchronisée accessible via un lien ou bouton adjacent.

Démo volontairement fautive

Voir le code source du piège
<video src="media/video.mp4" controls></video>

Ce qui ne va pas : Pour un média temporel pré-enregistré seulement vidéo, le contenu doit être accessible autrement : version alternative « audio seulement », transcription textuelle ou audiodescription synchronisée. Aucune de ces alternatives n'est proposée ici.

Comment corriger : Fournir au moins une des alternatives exigées, accessible via un lien ou bouton adjacent. L'alternative peut aussi être directement adjacente, à condition d'être clairement identifiable.

WCAG :
  • 1.2.1 Audio-only and Video-only (Prerecorded) (A)
  • 1.2.3 Audio Description or Media Alternative (Prerecorded) (A)

4.1.3 manuel

Chaque média temporel synchronisé pré-enregistré vérifie-t-il, si nécessaire, une de ces conditions (hors cas particuliers) ? Il existe une transcription textuelle accessible via un lien ou bouton adjacent ; Il existe une transcription textuelle adjacente clairement identifiable ; Il existe une audiodescription synchronisée ; Il existe une version alternative avec une audiodescription synchronisée accessible via un lien ou bouton adjacent.

Démo volontairement fautive

Voir le code source du piège
<video src="media/video.mp4" controls></video>

Ce qui ne va pas : Ce média temporel synchronisé (image et son) ne possède ni transcription textuelle ni audiodescription synchronisée. Les personnes qui ne peuvent pas voir l'image ou entendre le son sont privées d'une partie du contenu.

Comment corriger : Proposer une transcription textuelle complète, adjacente ou accessible via un lien adjacent. Une audiodescription synchronisée, ou une version alternative qui en contient une, est aussi acceptable.

WCAG :
  • 1.2.1 Audio-only and Video-only (Prerecorded) (A)
  • 1.2.3 Audio Description or Media Alternative (Prerecorded) (A)

4.2 — Pour chaque média temporel pré-enregistré ayant une transcription textuelle ou une audiodescription synchronisée, celles-ci sont-elles pertinentes (hors cas particuliers) ?

4.2.1 manuel

Pour chaque média temporel pré-enregistré seulement audio, ayant une transcription textuelle, celle-ci est-elle pertinente (hors cas particuliers) ?

Démo volontairement fautive

Transcription : un son a été émis.

Voir le code source du piège
<audio src="media/audio.mp3" controls></audio>
<p>Transcription : un son a été émis.</p>

Ce qui ne va pas : La transcription « un son a été émis » ne restitue pas le contenu réel du média (paroles, informations chiffrées, échanges) : elle est inexploitable. Une transcription présente mais non pertinente ne satisfait pas le critère.

Comment corriger : Produire une transcription fidèle et complète du média. Retranscrire l'intégralité des paroles et décrire les informations sonores essentielles dans l'ordre du déroulement.

WCAG :
  • 1.2.1 Audio-only and Video-only (Prerecorded) (A)
  • 1.2.3 Audio Description and Media Alternative (Prerecorded) (A)

4.2.2 manuel

Chaque média temporel pré-enregistré seulement vidéo vérifie-t-il une de ces conditions (hors cas particuliers) ? La transcription textuelle est pertinente ; L'audiodescription synchronisée est pertinente ; L'audiodescription synchronisée de la version alternative est pertinente ; La version alternative audio seulement est pertinente.

Démo volontairement fautive

Transcription : image fixe avec du son.

Voir le code source du piège
<video src="media/video.mp4" controls></video>
<p>Transcription : image fixe avec du son.</p>

Ce qui ne va pas : L'alternative proposée pour ce média seulement vidéo ne décrit ni les actions visuelles ni le contenu des dialogues : elle ne permet pas d'accéder au même contenu. Transcription, audiodescription et version audio seulement doivent toutes être pertinentes.

Comment corriger : Rédiger une transcription exhaustive, dialogues et description des informations visuelles compris. Vérifier de la même façon que l'audiodescription ou la version audio seulement restitue bien tout le contenu.

WCAG :
  • 1.2.1 Audio-only and Video-only (Prerecorded) (A)
  • 1.2.3 Audio Description and Media Alternative (Prerecorded) (A)

4.2.3 manuel

Chaque média temporel synchronisé pré-enregistré vérifie-t-il une de ces conditions (hors cas particuliers) ? La transcription textuelle est pertinente ; L'audiodescription synchronisée est pertinente ; L'audiodescription synchronisée de la version alternative est pertinente.

Démo volontairement fautive

Transcription : séquence vidéo quelconque.

Voir le code source du piège
<video src="media/video.mp4" controls></video>
<p>Transcription : séquence vidéo quelconque.</p>

Ce qui ne va pas : La transcription « séquence vidéo quelconque » est trop vague pour restituer les échanges et les informations visuelles essentielles du média synchronisé. Elle n'apporte aucune information utile à la personne qui ne peut pas consulter le média.

Comment corriger : Fournir une transcription complète et fidèle : dialogues, bruitages signifiants et informations visuelles essentielles. Une audiodescription synchronisée pertinente est également une solution valable.

WCAG :
  • 1.2.1 Audio-only and Video-only (Prerecorded) (A)
  • 1.2.3 Audio Description and Media Alternative (Prerecorded) (A)

4.3 — Chaque média temporel synchronisé pré-enregistré a-t-il, si nécessaire, des sous-titres synchronisés (hors cas particuliers) ?

4.3.1 partiel

Chaque média temporel synchronisé pré-enregistré vérifie-t-il, si nécessaire, l'une de ces conditions (hors cas particuliers) ? Le média temporel synchronisé possède des sous-titres synchronisés ; Il existe une version alternative possédant des sous-titres synchronisés accessible via un lien ou bouton adjacent.

Démo volontairement fautive

Voir le code source du piège
<video src="media/video.mp4" controls></video>

Ce qui ne va pas : Le média synchronisé ne possède pas de sous-titres synchronisés : aucune balise <track kind="captions"> n'est présente, ni version alternative sous-titrée. axe-core renvoie incomplete sur les pistes vidéo : il faut confirmer humainement que des sous-titres sont bien nécessaires et absents.

Comment corriger : Ajouter une piste de sous-titres dans la balise video : <track kind="captions" src="sous-titres.vtt" srclang="fr" label="Français">. Proposer une version alternative sous-titrée est aussi acceptable.

WCAG :
  • 1.2.2 Captions (Prerecorded) (A)

4.3.2 partiel

Pour chaque média temporel synchronisé pré-enregistré possédant des sous-titres synchronisés diffusés via une balise <track>, la balise <track> possède-t-elle un attribut kind="captions" ?

Démo volontairement fautive

Voir le code source du piège
<video src="media/video.mp4" controls>
  <track src="media/sous-titres.vtt" kind="subtitles" srclang="fr" label="Français">
</video>

Ce qui ne va pas : La piste est déclarée kind="subtitles" alors que le RGAA exige kind="captions" : les sous-titres pour sourds et malentendants doivent couvrir dialogues ET informations sonores. axe-core signale un doute (incomplete) qui demande confirmation humaine.

Comment corriger : Remplacer kind="subtitles" par kind="captions" : <track kind="captions" src="sous-titres.vtt" srclang="fr">. Vérifier ensuite que la piste est bien reconnue comme piste de sous-titres par le lecteur.

WCAG :
  • 1.2.2 Captions (Prerecorded) (A)

4.4 — Pour chaque média temporel synchronisé pré-enregistré ayant des sous-titres synchronisés, ces sous-titres sont-ils pertinents ?

4.4.1 manuel

Pour chaque média temporel synchronisé pré-enregistré ayant des sous-titres synchronisés, ces sous-titres sont-ils pertinents ?

Démo volontairement fautive

Voir le code source du piège
<video src="media/video.mp4" controls>
  <track kind="captions" src="media/sous-titres.vtt" srclang="fr" label="Français">
</video>

Ce qui ne va pas : La piste de sous-titres existe mais son contenu n'est pas pertinent : elle ne retranscrit qu'une partie des répliques, est désynchronisée ou omet des informations sonores essentielles. La présence d'une piste ne suffit pas, encore faut-il qu'elle soit exacte et complète.

Comment corriger : Vérifier humainement le fichier de sous-titres : chaque réplique et information sonore doit être retranscrite, correctement orthographiée et synchronisée avec le média. Corriger les passages manquants ou désynchronisés.

WCAG :
  • 1.2.2 Captions (Prerecorded) (A)

4.5 — Chaque média temporel pré-enregistré a-t-il, si nécessaire, une audiodescription synchronisée (hors cas particuliers) ?

4.5.1 manuel

Chaque média temporel pré-enregistré seulement vidéo vérifie-t-il, si nécessaire, une de ces conditions (hors cas particuliers) ? Il existe une audiodescription synchronisée ; Il existe une version alternative avec une audiodescription synchronisée.

Démo volontairement fautive

Voir le code source du piège
<video src="media/video.mp4" controls></video>

Ce qui ne va pas : Pour ce média seulement vidéo, une audiodescription synchronisée (ou une version alternative qui en contient une) est nécessaire dès que des informations passent par l'image. Aucune audiodescription n'est proposée.

Comment corriger : Fournir une audiodescription synchronisée du média. À défaut, proposer une version alternative avec audiodescription, accessible via un lien ou bouton adjacent.

WCAG :
  • 1.2.5 Audio Description (Prerecorded) (AA)

4.5.2 manuel

Chaque média temporel synchronisé pré-enregistré vérifie-t-il, si nécessaire, une de ces conditions (hors cas particuliers) ? Il existe une audiodescription synchronisée ; Il existe une version alternative avec une audiodescription synchronisée.

Démo volontairement fautive

Voir le code source du piège
<video src="media/video.mp4" controls></video>

Ce qui ne va pas : Ce média synchronisé transmet des informations essentielles par l'image mais ne propose aucune audiodescription synchronisée, ni version alternative qui en contienne une. Les personnes aveugles ou malvoyantes perdent ces informations.

Comment corriger : Ajouter une audiodescription synchronisée, par exemple une piste kind="descriptions" ou une version dédiée. La rendre accessible via un lien ou bouton adjacent clairement identifiable.

WCAG :
  • 1.2.5 Audio Description (Prerecorded) (AA)

4.6 — Pour chaque média temporel pré-enregistré ayant une audiodescription synchronisée, celle-ci est-elle pertinente ?

4.6.1 manuel

Pour chaque média temporel pré-enregistré seulement vidéo ayant une audiodescription synchronisée, celle-ci est-elle pertinente ?

Démo volontairement fautive

Voir le code source du piège
<video src="media/video.mp4" controls>
  <track kind="descriptions" src="media/description.vtt" srclang="fr" label="Audiodescription">
</video>

Ce qui ne va pas : L'audiodescription proposée pour ce média seulement vidéo n'est pas pertinente : elle se contente de répéter les dialogues et ne décrit pas les actions et informations visuelles essentielles. Une audiodescription inutile ne compense pas l'absence d'accès à l'image.

Comment corriger : Rédiger une audiodescription qui insère, dans les silences de la bande son, la description des actions, personnages et informations visuelles nécessaires à la compréhension. Elle doit compléter le dialogue sans le masquer.

WCAG :
  • 1.2.5 Audio Description (Prerecorded) (AA)

4.6.2 manuel

Pour chaque média temporel synchronisé ayant une audiodescription synchronisée, celle-ci est-elle pertinente ?

Démo volontairement fautive

Voir le code source du piège
<video src="media/video.mp4" controls>
  <track kind="descriptions" src="media/description.vtt" srclang="fr" label="Audiodescription">
</video>

Ce qui ne va pas : L'audiodescription synchronisée de ce média est incomplète : plusieurs séquences visuelles porteuses de sens ne sont pas décrites. Le critère exige une audiodescription pertinente, qui restitue l'ensemble des informations visuelles essentielles.

Comment corriger : Vérifier la couverture de l'audiodescription sur toute la durée du média et compléter les passages manquants. Respecter la synchronisation avec l'image et la bande son.

WCAG :
  • 1.2.5 Audio Description (Prerecorded) (AA)

4.7 — Chaque média temporel est-il clairement identifiable (hors cas particuliers) ?

4.7.1 manuel

Pour chaque média temporel seulement son, seulement vidéo ou synchronisé, le contenu textuel adjacent permet-il d'identifier clairement le média temporel (hors cas particuliers) ?

Démo volontairement fautive

Voir le code source du piège
<video src="media/video.mp4" controls></video>

Ce qui ne va pas : Aucun contenu textuel adjacent ne permet d'identifier le sujet de ce média temporel. Un utilisateur de lecteur d'écran ne sait pas de quoi il s'agit avant de lancer la lecture, et une personne malvoyante ne peut pas décider de le consulter.

Comment corriger : Ajouter à proximité immédiate du lecteur un intitulé descriptif, par exemple « Reportage : la récolte du miel en Ardèche ». Ce texte doit permettre d'identifier clairement le média sans le lire.

WCAG :
  • 1.1.1 Non-text Content (A)

4.8 — Chaque média non temporel a-t-il, si nécessaire, une alternative (hors cas particuliers) ?

4.8.1 manuel

Chaque média non temporel vérifie-t-il, si nécessaire, une de ces conditions (hors cas particuliers) ? Un lien ou un bouton adjacent, clairement identifiable, permet d’accéder à une page contenant une alternative ; Un lien ou un bouton adjacent, clairement identifiable, permet d'accéder à une alternative dans la page.

Démo volontairement fautive

Voir le code source du piège
<canvas id="f-4-8-1-graphique" width="300" height="150"></canvas>

Ce qui ne va pas : Ce média non temporel (un canvas destiné à afficher un graphique) n'est associé à aucune alternative : ni lien ni bouton adjacent permettant d'accéder à une page ou à une zone de la page contenant l'alternative. Les technologies d'assistance n'ont accès à aucune information.

Comment corriger : Ajouter un lien ou bouton adjacent, clairement identifiable, qui mène à une alternative complète du graphique. L'alternative peut être une description textuelle ou un tableau de données, dans la page ou sur une page dédiée.

WCAG :
  • 1.1.1 Non-text Content (A)

4.8.2 manuel

Chaque média non temporel associé à une alternative vérifie-t-il une de ces conditions (hors cas particuliers) ? La page référencée par le lien ou bouton adjacent est accessible ; L'alternative dans la page, référencée par le lien ou bouton adjacent, est accessible.

Démo volontairement fautive

Voir le code source du piège
<canvas id="f-4-8-2-graphique" width="300" height="150"></canvas>
<p><a href="#alternative-graphique">Voir l'alternative</a></p>

Ce qui ne va pas : Le lien adjacent « Voir l'alternative » pointe vers une ancre #alternative-graphique qui n'existe pas dans la page : l'alternative annoncée est inaccessible. Un lien cassé ne satisfait pas le critère d'accessibilité de l'alternative.

Comment corriger : Faire pointer le lien vers une ancre réellement présente dans la page, ou vers une page accessible contenant l'alternative. Vérifier que la destination se charge correctement et expose bien le contenu.

WCAG :
  • 1.1.1 Non-text Content (A)

4.9 — Pour chaque média non temporel ayant une alternative, cette alternative est-elle pertinente ?

4.9.1 manuel

Pour chaque média non temporel ayant une alternative, cette alternative permet-elle d'accéder au même contenu et à des fonctionnalités similaires ?

Démo volontairement fautive

Voir l'alternative

Un graphique est affiché.

Voir le code source du piège
<canvas id="f-4-9-1-graphique" width="300" height="150"></canvas>
<p><a href="#f-4-9-1-alternative">Voir l'alternative</a></p>
<p id="f-4-9-1-alternative">Un graphique est affiché.</p>

Ce qui ne va pas : L'alternative « Un graphique est affiché » ne permet pas d'accéder au même contenu que le média non temporel : les données du graphique ne sont pas restituées. L'alternative doit donner accès au même contenu et à des fonctionnalités similaires.

Comment corriger : Remplacer cette phrase par une restitution complète des données, par exemple un tableau de valeurs. Une description détaillée du graphique, mentionnant les tendances et valeurs clés, est également acceptable.

WCAG :
  • 1.1.1 Non-text Content (A)

4.10 — Chaque son déclenché automatiquement est-il contrôlable par l'utilisateur ?

4.10.1 partiel

Chaque séquence sonore déclenchée automatiquement via une balise <object>, <video>, <audio>, <embed>, <bgsound> ou un code JavaScript vérifie-t-elle une de ces conditions ? La séquence sonore a une durée inférieure ou égale à 3 secondes ; La séquence sonore peut être stoppée sur action de l'utilisateur ; Le volume de la séquence sonore peut être contrôlé par l'utilisateur indépendamment du contrôle de volume du système.

Démo volontairement fautive

Voir le code source du piège
<audio src="media/audio.mp3" autoplay loop></audio>

Ce qui ne va pas : Le son se déclenche automatiquement au chargement de la page et se répète en boucle sans qu'aucun contrôle ne soit proposé. axe-core ne peut pas vérifier seul la durée effective du son (résultat incomplete) : la validation humaine est nécessaire.

Comment corriger : Supprimer l'attribut autoplay, ou fournir des contrôles (controls) permettant de stopper le son et de régler le volume. Une durée inférieure ou égale à 3 secondes sans boucle serait aussi acceptable.

WCAG :
  • 1.4.2 Audio Control (A)

4.11 — La consultation de chaque média temporel est-elle, si nécessaire, contrôlable par le clavier et tout dispositif de pointage ?

4.11.1 manuel

Chaque média temporel a-t-il, si nécessaire, les fonctionnalités de contrôle de sa consultation ?

Démo volontairement fautive

Voir le code source du piège
<video src="media/video.mp4"></video>

Ce qui ne va pas : Ce média temporel ne possède aucune fonctionnalité de contrôle de consultation : pas d'attribut controls, pas de lecteur personnalisé. Il est impossible de lancer, mettre en pause ou régler le volume, ni à la souris ni au clavier.

Comment corriger : Ajouter l'attribut controls à la balise video. Si un lecteur personnalisé est utilisé, il doit offrir l'ensemble des fonctionnalités de contrôle de façon accessible.

WCAG :
  • 2.1.1 Keyboard (A)
  • 2.1.2 No Keyboard Trap (A)

4.11.2 manuel

Pour chaque média temporel, chaque fonctionnalité vérifie-t-elle une de ces conditions ? La fonctionnalité est accessible par le clavier et tout dispositif de pointage ; Une fonctionnalité accessible par le clavier et tout dispositif de pointage permettant de réaliser la même action est présente dans la page.

Démo volontairement fautive

Lancer la lecture
Voir le code source du piège
<video src="media/video.mp4"></video>
<span onclick="document.querySelector('video').play()">Lancer la lecture</span>

Ce qui ne va pas : La fonctionnalité de lecture est portée par un <span> qui n'est ni focusable ni activable au clavier : seul un clic souris permet de lancer la vidéo. Les utilisateurs de clavier n'ont aucun moyen d'accéder à cette fonctionnalité.

Comment corriger : Utiliser un <button> natif : <button onclick="...">Lancer la lecture</button>. À défaut, un élément avec role="button", tabindex="0" et une gestion des touches Entrée/Espace est acceptable.

WCAG :
  • 2.1.1 Keyboard (A)
  • 2.1.2 No Keyboard Trap (A)

4.11.3 manuel

Pour chaque média temporel, chaque fonctionnalité vérifie-t-elle une de ces conditions ? La fonctionnalité est activable par le clavier et tout dispositif de pointage ; Une fonctionnalité activable par le clavier et tout dispositif de pointage permettant de réaliser la même action est présente dans la page.

Démo volontairement fautive

Pause
Voir le code source du piège
<video src="media/video.mp4"></video>
<div role="button" tabindex="0" onclick="document.querySelector('video').pause()">Pause</div>

Ce qui ne va pas : Le contrôle « Pause » est focusable mais son activation au clavier n'est pas gérée : la touche Entrée ou Espace ne déclenche aucune action, seul le clic souris fonctionne. La fonctionnalité n'est donc pas activable par le clavier.

Comment corriger : Gérer les événements clavier (Entrée et Espace) sur cet élément. Utiliser un <button> natif reste la solution la plus simple, car il fournit cette gestion automatiquement.

WCAG :
  • 2.1.1 Keyboard (A)
  • 2.1.2 No Keyboard Trap (A)

4.12 — La consultation de chaque média non temporel est-elle contrôlable par le clavier et tout dispositif de pointage ?

4.12.1 manuel

Pour chaque média non temporel, chaque fonctionnalité vérifie-t-elle une de ces conditions ? La fonctionnalité est accessible par le clavier et tout dispositif de pointage ; Une fonctionnalité accessible par le clavier et tout dispositif de pointage permettant de réaliser la même action est présente dans la page.

Démo volontairement fautive

Zoomer sur la carte

Voir le code source du piège
<canvas id="f-4-12-1-carte" width="300" height="150"></canvas>
<p onclick="document.querySelector('canvas').focus()">Zoomer sur la carte</p>

Ce qui ne va pas : Les fonctionnalités de ce média non temporel (la carte interactive) ne sont pas accessibles par le clavier : le contrôle « Zoomer sur la carte » est un <p> non focusable, et le canvas lui-même n'offre aucune prise au clavier. Seule la souris fonctionne.

Comment corriger : Rendre chaque fonctionnalité accessible par le clavier : éléments focusables et gestion des touches. Proposer si besoin une alternative accessible permettant de réaliser les mêmes actions.

WCAG :
  • 2.1.1 Keyboard (A)
  • 2.1.2 No Keyboard Trap (A)

4.12.2 manuel

Pour chaque média non temporel, chaque fonctionnalité vérifie-t-elle une de ces conditions ? La fonctionnalité est activable par le clavier et tout dispositif de pointage ; Une fonctionnalité activable par le clavier et tout dispositif de pointage permettant de réaliser la même action est présente dans la page.

Démo volontairement fautive

Afficher les détails
Voir le code source du piège
<canvas id="f-4-12-2-graphique" width="300" height="150"></canvas>
<div tabindex="0" onclick="document.querySelector('canvas').focus()">Afficher les détails</div>

Ce qui ne va pas : Le contrôle « Afficher les détails » de ce média non temporel est focusable (tabindex="0") mais son activation au clavier n'est pas gérée : la touche Entrée ou Espace ne déclenche rien. La fonctionnalité n'est donc activable ni par le clavier ni par un autre dispositif de pointage que la souris.

Comment corriger : Associer une gestion des touches Entrée/Espace à l'élément, ou utiliser un <button> natif. Proposer une alternative offrant les mêmes fonctionnalités si le média lui-même ne peut pas être rendu accessible.

WCAG :
  • 2.1.1 Keyboard (A)
  • 2.1.2 No Keyboard Trap (A)

4.13 — Chaque média temporel et non temporel est-il compatible avec les technologies d'assistance (hors cas particuliers) ?

4.13.1 manuel

Chaque média temporel et non temporel vérifie-t-il une de ces conditions (hors cas particuliers) ? Le nom, le rôle, la valeur, le paramétrage et les changements d'états des composants d'interfaces sont accessibles aux technologies d'assistance via une API d'accessibilité ; Une alternative compatible avec une API d'accessibilité permet d'accéder aux mêmes fonctionnalités.

Démo volontairement fautive

Lecture
Voir le code source du piège
<video src="media/video.mp4"></video>
<span onclick="document.querySelector('video').play()">Lecture</span>

Ce qui ne va pas : Le composant d'interface « Lecture » est un <span> sans rôle ARIA ni nom accessible : les technologies d'assistance ne peuvent ni l'identifier, ni connaître son état, ni l'activer via une API d'accessibilité. Le média n'est pas compatible avec les technologies d'assistance.

Comment corriger : Utiliser des éléments natifs (<button>, controls) qui exposent nom, rôle et valeur via l'API d'accessibilité. Pour un composant personnalisé, déclarer role="button", aria-label et l'état avec aria-pressed.

WCAG :
  • 4.1.2 Name, Role, Value (A)

4.13.2 manuel

Chaque média temporel et non temporel qui possède une alternative compatible avec les technologies d'assistance, vérifie-t-il une de ces conditions ? L'alternative est adjacente au média temporel ou non temporel ; L'alternative est accessible via un lien ou bouton adjacent ; Un mécanisme permet de remplacer le média temporel ou non temporel par son alternative.

Démo volontairement fautive

La transcription de cette vidéo se trouve en bas de page.

Voir le code source du piège
<video src="media/video.mp4" controls></video>
<p>La transcription de cette vidéo se trouve en bas de page.</p>

Ce qui ne va pas : L'alternative (la transcription) n'est ni adjacente au média, ni accessible via un lien ou bouton adjacent, et aucun mécanisme ne permet de remplacer le média par son alternative. Elle est introuvable pour un utilisateur de lecteur d'écran qui parcourt la page.

Comment corriger : Placer la transcription juste à côté du lecteur, ou la rendre accessible par un lien/bouton adjacent clairement identifiable. Un mécanisme de remplacement du média par son alternative est aussi une solution valable.

WCAG :
  • 4.1.2 Name, Role, Value (A)

5. Tableaux (15 tests)

Les tableaux de données doivent être structurés (résumé, titres, en-têtes, portée) ; les tableaux de mise en forme ne doivent pas être détournés.

5.1 — Chaque tableau de données complexe a-t-il un résumé ?

5.1.1 manuel

Pour chaque tableau de données complexe, un résumé est-il disponible ?

Démo volontairement fautive

Ventes par région
Région20232024
CAMargesCAMarges
Nord1203014035
Voir le code source du piège
<table>
  <caption>Ventes par région</caption>
  <tr><th rowspan="2">Région</th><th colspan="2">2023</th><th colspan="2">2024</th></tr>
  <tr><th>CA</th><th>Marges</th><th>CA</th><th>Marges</th></tr>
  <tr><td>Nord</td><td>120</td><td>30</td><td>140</td><td>35</td></tr>
</table>

Ce qui ne va pas : Ce tableau de données complexe (en-têtes sur deux niveaux, cellules fusionnées) ne possède aucun résumé. Sans résumé, un utilisateur de lecteur d'écran ne peut pas anticiper la structure du tableau avant de le parcourir.

Comment corriger : Ajouter un résumé décrivant la structure du tableau, par exemple via l'attribut summary="Ventes et marges par région sur 2023 et 2024, avec en-têtes sur deux niveaux". Le résumé doit aider à comprendre comment le tableau est organisé.

WCAG :
  • 1.3.1 Info and Relationships (A)

5.2 — Pour chaque tableau de données complexe ayant un résumé, celui-ci est-il pertinent ?

5.2.1 manuel

Pour chaque tableau de données complexe ayant un résumé, celui-ci est-il pertinent ?

Démo volontairement fautive

Ventes par région
Région2023
CAMarges
Nord12030
Voir le code source du piège
<table summary="Tableau">
  <caption>Ventes par région</caption>
  <tr><th rowspan="2">Région</th><th colspan="2">2023</th></tr>
  <tr><th>CA</th><th>Marges</th></tr>
  <tr><td>Nord</td><td>120</td><td>30</td></tr>
</table>

Ce qui ne va pas : Le résumé « Tableau » est présent mais non pertinent : il ne décrit ni le contenu ni la structure à deux niveaux d'en-têtes. Il n'aide donc pas à comprendre comment parcourir le tableau, et un résumé inutile équivaut à une absence de résumé.

Comment corriger : Rédiger un résumé décrivant la structure, par exemple « Ventes et marges par région en 2023, avec en-têtes de colonnes sur deux niveaux ». Vérifier qu'il apporte une information qui ne figure pas déjà dans le titre.

WCAG :
  • 1.3.1 Info and Relationships (A)

5.3 — Pour chaque tableau de mise en forme, le contenu linéarisé reste-t-il compréhensible ?

5.3.1 manuel

Chaque tableau de mise en forme vérifie-t-il ces conditions ? Le contenu linéarisé reste compréhensible ; La balise <table> possède un attribut role="presentation".

Démo volontairement fautive

Voir le code source du piège
<table>
  <tr><td><a href="#">Accueil</a></td><td><a href="#">Contact</a></td></tr>
</table>

Ce qui ne va pas : Ce tableau ne sert qu'à la mise en page (aligner des liens) mais sa balise <table> ne possède pas role="presentation". Les technologies d'assistance l'annoncent comme un tableau de données alors qu'il n'en est pas un, ce qui crée de la confusion.

Comment corriger : Ajouter role="presentation" à la balise <table>, après avoir vérifié que le contenu linéarisé reste compréhensible. Mieux encore : remplacer le tableau par une mise en page CSS.

WCAG :
  • 1.3.2 Meaningful Sequence (A)
  • 4.1.2 Name, Role, Value (A)

5.4 — Pour chaque tableau de données ayant un titre, le titre est-il correctement associé au tableau de données ?

5.4.1 manuel

Pour chaque tableau de données ayant un titre, le titre est-il correctement associé au tableau de données ?

Démo volontairement fautive

Ventes par région

RégionCA
Nord120
Voir le code source du piège
<p><strong>Ventes par région</strong></p>
<table>
  <tr><th>Région</th><th>CA</th></tr>
  <tr><td>Nord</td><td>120</td></tr>
</table>

Ce qui ne va pas : Le titre est un simple paragraphe placé au-dessus du tableau : il n'est pas associé au tableau. Un utilisateur de lecteur d'écran qui navigue dans le tableau n'entend jamais ce titre, qui ne permet pas d'identifier le tableau.

Comment corriger : Utiliser un <caption> comme premier enfant du tableau : <table><caption>Ventes par région</caption>.... Le navigateur et les technologies d'assistance associent alors automatiquement le titre au tableau.

WCAG :
  • 1.3.1 Info and Relationships (A)

5.5 — Pour chaque tableau de données ayant un titre, celui-ci est-il pertinent ?

5.5.1 manuel

Pour chaque tableau de données ayant un titre, ce titre permet-il d'identifier le contenu du tableau de données de manière claire et concise ?

Démo volontairement fautive

Résultats
RégionCA
Nord120
Voir le code source du piège
<table>
  <caption>Résultats</caption>
  <tr><th>Région</th><th>CA</th></tr>
  <tr><td>Nord</td><td>120</td></tr>
</table>

Ce qui ne va pas : Le titre « Résultats » est trop vague pour identifier le contenu du tableau : on ignore s'il s'agit de ventes, d'un sondage ou d'autre chose. Le titre doit permettre d'identifier le contenu de manière claire et concise.

Comment corriger : Choisir un titre explicite, par exemple « Chiffre d'affaires par région en 2024 ». Il doit décrire le contenu sans être ni trop long ni trop générique.

WCAG :
  • 1.3.1 Info and Relationships (A)

5.6 — Pour chaque tableau de données, chaque en-tête de colonne et chaque en-tête de ligne sont-ils correctement déclarés ?

5.6.1 manuel

Pour chaque tableau de données, chaque en-tête de colonne s'appliquant à la totalité de la colonne vérifie-t-il une de ces conditions ? L'en-tête de colonnes est structuré au moyen d'une balise <th> ; L'en-tête de colonnes est structuré au moyen d'une balise pourvue d'un attribut WAI-ARIA role="columnheader".

Démo volontairement fautive

RégionCA
Nord120
Voir le code source du piège
<table>
  <tr><td><strong>Région</strong></td><td><strong>CA</strong></td></tr>
  <tr><td>Nord</td><td>120</td></tr>
</table>

Ce qui ne va pas : Les en-têtes de colonnes « Région » et « CA » sont des <td> mis en gras au lieu de <th>. Ils ne sont pas reconnus comme en-têtes par les technologies d'assistance, qui ne peuvent pas associer les valeurs à leur colonne.

Comment corriger : Structurer chaque en-tête de colonne avec une balise <th> : <th scope="col">Région</th> et <th scope="col">CA</th>. Le gras seul n'a aucune valeur sémantique pour les technologies d'assistance.

WCAG :
  • 1.3.1 Info and Relationships (A)

5.6.2 manuel

Pour chaque tableau de données, chaque en-tête de ligne s'appliquant à la totalité de la ligne vérifie-t-il une de ces conditions ? L'en-tête de lignes est structuré au moyen d'une balise <th> ; L'en-tête de lignes est structuré au moyen d'une balise pourvue d'un attribut WAI-ARIA role="rowheader".

Démo volontairement fautive

RégionCA
Nord120
Sud90
Voir le code source du piège
<table>
  <tr><th>Région</th><th>CA</th></tr>
  <tr><td>Nord</td><td>120</td></tr>
  <tr><td>Sud</td><td>90</td></tr>
</table>

Ce qui ne va pas : Les en-têtes de lignes (les noms des régions dans la première colonne) sont des <td>. Un lecteur d'écran ne peut donc pas associer chaque valeur de CA à sa région.

Comment corriger : Remplacer ces cellules par des <th scope="row"> : <th scope="row">Nord</th> et <th scope="row">Sud</th>. L'en-tête de ligne doit s'appliquer à la totalité de la ligne.

WCAG :
  • 1.3.1 Info and Relationships (A)

5.6.3 manuel

Pour chaque tableau de données, chaque en-tête ne s'appliquant pas à la totalité de la ligne ou de la colonne est-il structuré au moyen d'une balise <th> ?

Démo volontairement fautive

Zone Nord
RégionCAMarges
Picardie8020
Voir le code source du piège
<table>
  <tr><td colspan="3"><strong>Zone Nord</strong></td></tr>
  <tr><th>Région</th><th>CA</th><th>Marges</th></tr>
  <tr><td>Picardie</td><td>80</td><td>20</td></tr>
</table>

Ce qui ne va pas : L'en-tête « Zone Nord » ne s'applique pas à la totalité d'une ligne ou d'une colonne : il couvre un groupe de colonnes via colspan. Structuré en <td>, il n'est pas reconnu comme en-tête de groupe.

Comment corriger : Le structurer en <th> avec un id unique, sans scope ni rôle rowheader/columnheader : <th id="f-5-6-3-zone" colspan="3">Zone Nord</th>. Relier ensuite les cellules concernées via headers.

WCAG :
  • 1.3.1 Info and Relationships (A)

5.6.4 manuel

Pour chaque tableau de données, chaque cellule associée à plusieurs en-têtes est-elle structurée au moyen d’une balise <td> ou <th> ?

Démo volontairement fautive

Région CA 2024
Nord 120
Voir le code source du piège
<div role="table" aria-label="Résultats par région">
  <div role="row">
    <span role="columnheader">Région</span>
    <span role="columnheader">CA 2024</span>
  </div>
  <div role="row">
    <span role="rowheader">Nord</span>
    <span>120</span>
  </div>
</div>

Ce qui ne va pas : La cellule « 120 » est associée à plusieurs en-têtes (Région et CA 2024) mais elle est structurée avec un simple <span> sans rôle de cellule : elle n'est ni un <td>/<th> ni un role="cell". L'association avec ses en-têtes est perdue pour les technologies d'assistance.

Comment corriger : Structurer chaque cellule en <td>/<th> (ou role="cell" en contexte ARIA). Relier les cellules multi-en-têtes à leurs en-têtes, par exemple via l'attribut headers.

WCAG :
  • 1.3.1 Info and Relationships (A)

5.7 — Pour chaque tableau de données, la technique appropriée permettant d'associer chaque cellule avec ses en-têtes est-elle utilisée (hors cas particuliers) ?

5.7.1 manuel

Pour chaque contenu de balise <th> s'appliquant à la totalité de la ligne ou de la colonne, la balise <th> respecte-t-elle une de ces conditions (hors cas particuliers) ? La balise <th> possède un attribut id unique ; La balise <th> possède un attribut scope ; La balise <th> possède un attribut WAI-ARIA role="rowheader" ou role="columnheader".

Démo volontairement fautive

RégionCA
Nord120
Voir le code source du piège
<table>
  <tr><th>Région</th><th>CA</th></tr>
  <tr><td>Nord</td><td>120</td></tr>
</table>

Ce qui ne va pas : Les <th> s'appliquant à la totalité de leur colonne ne possèdent ni id unique, ni attribut scope, ni rôle ARIA rowheader/columnheader. Leur portée ne peut pas être déterminée de façon fiable par toutes les technologies d'assistance.

Comment corriger : Ajouter scope="col" sur chaque en-tête de colonne et scope="row" sur les en-têtes de ligne. Pour les tableaux complexes, utiliser des id uniques associés à des headers sur les cellules.

WCAG :
  • 1.3.1 Info and Relationships (A)

5.7.2 partiel

Pour chaque contenu de balise <th> s'appliquant à la totalité de la ligne ou de la colonne et possédant un attribut scope, la balise <th> vérifie-t-elle une de ces conditions ? La balise <th> possède un attribut scope avec la valeur "row" pour les en-têtes de ligne ; La balise <th> possède un attribut scope avec la valeur "col" pour les en-têtes de colonne.

Démo volontairement fautive

RégionCA
Nord120
Voir le code source du piège
<table>
  <tr><th scope="colonne">Région</th><th scope="col">CA</th></tr>
  <tr><td>Nord</td><td>120</td></tr>
</table>

Ce qui ne va pas : L'en-tête de colonne « Région » utilise scope="colonne", une valeur non reconnue : les valeurs autorisées sont row, col, rowgroup et colgroup. L'association entre l'en-tête et les cellules de sa colonne est perdue.

Comment corriger : Utiliser scope="col" pour les en-têtes de colonne et scope="row" pour les en-têtes de ligne. Vérifier l'orthographe des valeurs : une faute de frappe suffit à casser l'association.

WCAG :
  • 1.3.1 Info and Relationships (A)

5.7.3 manuel

Pour chaque contenu de balise <th> ne s'appliquant pas à la totalité de la ligne ou de la colonne, la balise <th> vérifie-t-elle ces conditions ? La balise <th> ne possède pas d'attribut scope ; La balise <th> ne possède pas d'attribut WAI-ARIA role="rowheader" ou role="columnheader" ; La balise <th> possède un attribut id unique.

Démo volontairement fautive

2023
CAMarges
12030
Voir le code source du piège
<table>
  <tr><th colspan="2" scope="col">2023</th></tr>
  <tr><th>CA</th><th>Marges</th></tr>
  <tr><td>120</td><td>30</td></tr>
</table>

Ce qui ne va pas : Le <th> « 2023 » ne s'applique pas à la totalité d'une ligne ou d'une colonne (il couvre deux colonnes via colspan). Il ne doit porter ni scope, ni rôle rowheader/columnheader, et doit posséder un id unique : ici il porte un scope="col" interdit et aucun id.

Comment corriger : Retirer le scope et donner un id unique à ce <th>, par exemple id="f-5-7-3-annee". Relier ensuite les cellules concernées via l'attribut headers.

WCAG :
  • 1.3.1 Info and Relationships (A)

5.7.4 partiel

Pour chaque contenu de balise <td> ou <th> associée à un ou plusieurs en-têtes possédant un attribut id, la balise vérifie-t-elle ces conditions ? La balise possède un attribut headers ; L'attribut headers possède la liste des valeurs d'attribut id des en-têtes associés.

Démo volontairement fautive

Région2023
CAMarges
Nord12030
Voir le code source du piège
<table>
  <tr><th id="f-5-7-4-region" rowspan="2">Région</th><th id="f-5-7-4-annee" colspan="2">2023</th></tr>
  <tr><th id="f-5-7-4-ca">CA</th><th id="f-5-7-4-marges">Marges</th></tr>
  <tr><td>Nord</td><td>120</td><td>30</td></tr>
</table>

Ce qui ne va pas : Les en-têtes possèdent des attributs id, mais les cellules ne portent pas d'attribut headers listant ces identifiants. Dans un tableau à en-têtes multiples (rowspan/colspan), l'association ne peut pas être reconstituée sans headers.

Comment corriger : Ajouter sur chaque cellule la liste des ids de ses en-têtes, par exemple headers="f-5-7-4-region f-5-7-4-annee f-5-7-4-ca" sur la cellule « 120 ». L'ordre des ids dans l'attribut doit respecter l'ordre de lecture des en-têtes.

WCAG :
  • 1.3.1 Info and Relationships (A)

5.7.5 manuel

Pour chaque balise pourvue d'un attribut WAI-ARIA role="rowheader" ou role="columnheader" dont le contenu s'applique à la totalité de la ligne ou de la colonne, la balise vérifie-t-elle une de ces conditions ? La balise possède un attribut WAI-ARIA role="rowheader" pour les en-têtes de ligne ; La balise possède un attribut WAI-ARIA role="columnheader" pour les en-têtes de colonne.

Démo volontairement fautive

NomÂge
Jean30
Voir le code source du piège
<table>
  <tr><td role="rowheader">Nom</td><td role="rowheader">Âge</td></tr>
  <tr><td>Jean</td><td>30</td></tr>
</table>

Ce qui ne va pas : Les en-têtes « Nom » et « Âge » s'appliquent à des colonnes entières mais sont déclarés role="rowheader" au lieu de role="columnheader". Le rôle contredit la structure réelle et l'association avec les cellules est fausse.

Comment corriger : Utiliser role="columnheader" pour les en-têtes de colonnes et role="rowheader" pour les en-têtes de lignes. Dans un tableau natif, des <th> avec scope restent la solution la plus robuste.

WCAG :
  • 1.3.1 Info and Relationships (A)

5.8 — Chaque tableau de mise en forme ne doit pas utiliser d'éléments propres aux tableaux de données. Cette règle est-elle respectée ?

5.8.1 manuel

Chaque tableau de mise en forme (balise <table>) vérifie-t-il ces conditions ? Le tableau de mise en forme (balise <table>) n'a pas d’attribut summary (sinon vide) et ne contient pas de balises <caption>, <th>, <thead>, <tfoot>, <colgroup> ou de balises ayant un attribut WAI-ARIA role="rowheader", role="columnheader" ; Les cellules du tableau de mise en forme (balises <td>) ne possèdent pas d'attributs scope, headers, axis.

Démo volontairement fautive

Menu
Accueil
Voir le code source du piège
<table>
  <tr><th>Menu</th></tr>
  <tr><td><a href="#">Accueil</a></td></tr>
</table>

Ce qui ne va pas : Ce tableau ne sert qu'à la mise en forme mais contient une balise <th>, élément réservé aux tableaux de données. Les technologies d'assistance le traitent alors comme un tableau de données fantôme, ce qui pollue la navigation.

Comment corriger : Retirer toute balise propre aux tableaux de données : th, caption, summary, thead, tfoot, colgroup et rôles d'en-tête. Ajouter role="presentation" sur la balise <table>.

WCAG :
  • 1.3.1 Info and Relationships (A)

6. Liens (6 tests)

Chaque lien doit avoir un intitulé qui permet de comprendre sa fonction et sa destination, seul.

6.1 — Chaque lien est-il explicite (hors cas particuliers) ?

6.1.1 manuel

Chaque lien texte vérifie-t-il une de ces conditions (hors cas particuliers) ? L'intitulé de lien seul permet d'en comprendre la fonction et la destination ; L'intitulé de lien additionné au contexte du lien permet d'en comprendre la fonction et la destination.

Démo volontairement fautive

Voir le code source du piège
<a href="page2.html">Cliquez ici</a>

Ce qui ne va pas : L'intitulé « Cliquez ici » ne permet pas, seul ni même avec le contexte immédiat, de comprendre la fonction ou la destination du lien. Un utilisateur qui navigue par liste de liens entend une série de « Cliquez ici » sans aucune signification.

Comment corriger : Utiliser un intitulé explicite qui décrit la destination, par exemple « Consulter le rapport annuel 2024 ». Si le contexte est nécessaire, il doit être adjacent et sans ambiguïté.

WCAG :
  • 1.1.1 Non-text Content (A)
  • 2.4.4 Link Purpose (In Context) (A)
  • 2.5.3 Label in Name (A)

6.1.2 manuel

Chaque lien image vérifie-t-il une de ces conditions (hors cas particuliers) ? L'intitulé de lien seul permet d'en comprendre la fonction et la destination ; L'intitulé de lien additionné au contexte du lien permet d'en comprendre la fonction et la destination.

Démo volontairement fautive

Cliquez ici
Voir le code source du piège
<a href="page2.html"><img src="img/logo.png" alt="Cliquez ici" width="100" height="40"></a>

Ce qui ne va pas : L'alternative de cette image-lien (« Cliquez ici ») ne décrit ni la fonction ni la destination du lien. Un utilisateur de lecteur d'écran ne sait pas où ce lien mène.

Comment corriger : Remplacer le alt par un texte décrivant la destination, par exemple alt="Tarifs de nos formations". L'intitulé de lien doit permettre d'en comprendre la fonction et la destination.

WCAG :
  • 1.1.1 Non-text Content (A)
  • 2.4.4 Link Purpose (In Context) (A)
  • 2.5.3 Label in Name (A)

6.1.3 manuel

Chaque lien composite vérifie-t-il une de ces conditions (hors cas particuliers) ? L'intitulé de lien seul permet d'en comprendre la fonction et la destination ; L'intitulé de lien additionné au contexte du lien permet d'en comprendre la fonction et la destination.

Démo volontairement fautive

Voir le code source du piège
<a href="page2.html">En savoir plus <img src="img/logo.png" alt="" width="100" height="40"></a>

Ce qui ne va pas : L'intitulé composite de ce lien (texte « En savoir plus » + image décorative) ne permet pas de comprendre sa fonction ni sa destination, même en tenant compte du contexte. La navigation par liste de liens devient inexploitable.

Comment corriger : Donner un intitulé composite explicite, par exemple « En savoir plus sur la garantie ». Veiller à ce que l'image du lien composite soit décorative (alt="") ou porte une alternative utile.

WCAG :
  • 1.1.1 Non-text Content (A)
  • 2.4.4 Link Purpose (In Context) (A)
  • 2.5.3 Label in Name (A)

6.1.4 manuel

Chaque lien SVG vérifie-t-il une de ces conditions (hors cas particuliers) ? L'intitulé de lien seul permet d'en comprendre la fonction et la destination ; L'intitulé de lien additionné au contexte du lien permet d'en comprendre la fonction et la destination.

Démo volontairement fautive

Voir le code source du piège
<a href="page2.html"><svg width="24" height="24" role="img" aria-label="cliquez ici"><circle cx="12" cy="12" r="10"></circle></svg></a>

Ce qui ne va pas : Le lien SVG a pour nom accessible « cliquez ici », qui ne décrit ni la fonction ni la destination du lien. Un utilisateur de lecteur d'écran ne peut pas décider s'il doit suivre ce lien.

Comment corriger : Fournir un nom accessible explicite, par exemple aria-label="Accéder à la documentation de l'API". Un texte visible décrivant la destination est également acceptable.

WCAG :
  • 1.1.1 Non-text Content (A)
  • 2.4.4 Link Purpose (In Context) (A)
  • 2.5.3 Label in Name (A)

6.1.5 manuel

Pour chaque lien ayant un intitulé visible, le nom accessible du lien contient-il au moins l'intitulé visible (hors cas particuliers) ?

Démo volontairement fautive

Voir le code source du piège
<a href="page2.html" aria-label="Rapport financier 2024">Plus d'informations</a>

Ce qui ne va pas : Le nom accessible du lien (« Rapport financier 2024 ») ne contient pas l'intitulé visible (« Plus d'informations »). Les utilisateurs de commandes vocales qui énoncent le texte visible ne déclenchent pas le lien. La règle axe label-content-name-mismatch est expérimentale et n'est pas exécutée par ally-agent : contrôle manuel.

Comment corriger : Aligner le nom accessible sur l'intitulé visible : soit le même texte dans aria-label et dans le lien, soit supprimer l'aria-label si le texte visible suffit. Le nom accessible doit toujours contenir l'intitulé visible.

WCAG :
  • 1.1.1 Non-text Content (A)
  • 2.4.4 Link Purpose (In Context) (A)
  • 2.5.3 Label in Name (A)

6.2 — Dans chaque page web, chaque lien a-t-il un intitulé ?

6.2.1 axe · link-name

Dans chaque page web, chaque lien a-t-il un intitulé entre <a> et </a> ?

Démo volontairement fautive

Voir le code source du piège
<a href="page2.html"><img src="img/logo.png" alt="" width="100" height="40"></a>

Ce qui ne va pas : Cette image-lien a un alt vide : le lien ne possède aucun intitulé entre <a> et </a>. Un lecteur d'écran annonce simplement « lien » sans aucune information, et la navigation par liste de liens devient impossible.

Comment corriger : Donner un alt qui décrit la destination du lien, par exemple alt="Accueil du site". Ajouter un texte dans le lien est également une solution valable.

WCAG :
  • 1.1.1 Non-text Content (A)
  • 2.4.4 Link Purpose (In Context) (A)

7. Scripts (11 tests)

Les scripts et composants dynamiques doivent être accessibles : nom, rôle, valeur, gestion du focus, messages de statut.

7.1 — Chaque script est-il, si nécessaire, compatible avec les technologies d'assistance ?

7.1.1 axe · aria-input-field-name

Chaque script qui génère ou contrôle un composant d'interface vérifie-t-il, si nécessaire, une de ces conditions ? Le nom, le rôle, la valeur, le paramétrage et les changements d'états sont accessibles aux technologies d'assistance via une API d'accessibilité ; Un composant d'interface accessible permettant d'accéder aux mêmes fonctionnalités est présent dans la page ; Une alternative accessible permet d'accéder aux mêmes fonctionnalités.

Démo volontairement fautive

Volume

Voir le code source du piège
<p><span role="slider" aria-valuemin="0" aria-valuemax="100" aria-valuenow="50" tabindex="0"></span> Volume</p>

Ce qui ne va pas : Ce composant piloté par script expose un rôle slider, sa valeur (aria-valuenow) et son paramétrage, mais aucun nom accessible : le texte visible « Volume » n'est associé à aucun attribut (aria-label, aria-labelledby). Le lecteur d'écran annonce un curseur sans nom.

Comment corriger : Donner un nom accessible au composant : aria-label="Volume" sur le curseur, ou aria-labelledby pointant vers l'étiquette visible. Sans nom, le composant est inutilisable pour les technologies d'assistance.

WCAG :
  • 2.5.3 Label in Name (A)
  • 4.1.2 Name, Role, Value (A)

7.1.2 axe · aria-hidden-focus

Chaque script qui génère ou contrôle un composant d'interface respecte-t-il une de ces conditions ? Le composant d'interface est correctement restitué par les technologies d'assistance ; Une alternative accessible permet d'accéder aux mêmes fonctionnalités.

Démo volontairement fautive

Voir le code source du piège
<div role="button" aria-hidden="true" tabindex="0" onclick="alert('ok')">Valider</div>

Ce qui ne va pas : Ce composant interactif est marqué aria-hidden="true" : il est invisible pour les technologies d'assistance alors qu'il reste focusable et actionnable. Le lecteur d'écran ne le restitue pas (ni nom, ni rôle, ni état), le composant n'est donc pas correctement restitué et aucune alternative n'est proposée.

Comment corriger : Retirer aria-hidden et exposer correctement le composant : nom, rôle (button) et état doivent être restitués. Un vrai <button> natif évite ces pièges.

WCAG :
  • 2.5.3 Label in Name (A)
  • 4.1.2 Name, Role, Value (A)

7.1.3 manuel

Chaque script qui génère ou contrôle un composant d'interface vérifie-t-il ces conditions (hors cas particuliers) ? Le composant possède un nom pertinent ; Le nom accessible du composant contient au moins l'intitulé visible ; Le composant possède un rôle pertinent.

Démo volontairement fautive

Voir le code source du piège
<button aria-label="Fermer">OK</button>

Ce qui ne va pas : Le nom accessible du bouton (Fermer) ne contient pas son intitulé visible (OK). La règle axe label-content-name-mismatch est expérimentale et n'est pas exécutée par ally-agent : contrôle manuel.

Comment corriger : Aligner le nom accessible sur l'intitulé visible : <button aria-label="Fermer (OK)">OK</button> ou, idéalement, un libellé identique : <button>Fermer</button>.

WCAG :
  • 2.5.3 Label in Name (A)
  • 4.1.2 Name, Role, Value (A)

7.2 — Pour chaque script ayant une alternative, cette alternative est-elle pertinente ?

7.2.1 manuel

Chaque script débutant par la balise <script> et ayant une alternative vérifie-t-il une de ces conditions ? L'alternative entre <noscript> et </noscript> permet d'accéder à des contenus et des fonctionnalités similaires ; La page affichée, lorsque JavaScript est désactivé, permet d'accéder à des contenus et des fonctionnalités similaires ; La page alternative permet d'accéder à des contenus et des fonctionnalités similaires ; Le langage de script côté serveur permet d'accéder à des contenus et des fonctionnalités similaires ; L'alternative présente dans la page permet d'accéder à des contenus et des fonctionnalités similaires.

Démo volontairement fautive

Afficher les résultats

Voir le code source du piège
<p onclick="this.innerHTML='Résultats chargés.'">Afficher les résultats</p><noscript>Veuillez activer JavaScript.</noscript>

Ce qui ne va pas : La fonctionnalité dépend d'un script mais l'alternative <noscript> ne donne aucun accès à des contenus ou fonctionnalités similaires : elle se contente de demander d'activer JavaScript. Sans script, l'utilisateur n'a aucun moyen d'afficher les résultats.

Comment corriger : Fournir une vraie alternative : une page ou un mécanisme sans script permettant d'obtenir les mêmes contenus (par ex. un lien vers une version statique des résultats).

WCAG :
  • 1.1.1 Non-text Content (A)
  • 4.1.2 Name, Role, Value (A)

7.2.2 manuel

Chaque élément non textuel mis à jour par un script (dans la page, ou dans un cadre) et ayant une alternative vérifie-t-il ces conditions ? L'alternative de l'élément non textuel est mise à jour ; L'alternative mise à jour est pertinente.

Démo volontairement fautive

Graphique des ventes 2023
Voir le code source du piège
<img src="img/chart.png" width="160" height="100" alt="Graphique des ventes 2023" onclick="this.src='img/info.png'">

Ce qui ne va pas : Le script remplace l'image par une autre (img/info.png) mais l'alternative textuelle (alt) n'est pas mise à jour : elle continue de décrire l'ancien graphique. L'alternative devient fausse et induit en erreur les utilisateurs de technologies d'assistance.

Comment corriger : Lorsque le contenu de l'élément non textuel change, mettre à jour son alternative en même temps (par ex. modifier l'attribut alt dans le même script) pour qu'elle reflète le nouveau contenu.

WCAG :
  • 1.1.1 Non-text Content (A)
  • 4.1.2 Name, Role, Value (A)

7.3 — Chaque script est-il contrôlable par le clavier et par tout dispositif de pointage (hors cas particuliers) ?

7.3.1 manuel

Chaque élément possédant un gestionnaire d'événement contrôlé par un script vérifie-t-il une de ces conditions (hors cas particuliers) ? L'élément est accessible par le clavier et tout dispositif de pointage ; Un élément accessible par le clavier et tout dispositif de pointage permettant de réaliser la même action est présent dans la page.

Démo volontairement fautive

Cliquez ici
Voir le code source du piège
<div onclick="alert('ok')">Cliquez ici</div>

Ce qui ne va pas : Cet élément possède un gestionnaire d'événement (onclick) mais n'est ni focusable ni actionnable au clavier : pas de tabindex, pas de rôle de bouton. Un utilisateur clavier ne peut pas déclencher l'action, et aucun autre élément accessible ne la permet.

Comment corriger : Utiliser un élément nativement accessible : <button type="button" onclick="alert('ok')">Cliquez ici</button>, ou ajouter tabindex="0" et role="button" en gérant la touche Entrée.

WCAG :
  • 1.3.1 Info and Relationships (A)
  • 2.1.1 Keyboard (A)
  • 2.4.7 Focus Visible (AA)

7.3.2 manuel

Un script ne doit pas supprimer le focus d'un élément qui le reçoit. Cette règle est-elle respectée (hors cas particuliers) ?

Démo volontairement fautive

Voir le code source du piège
<a href="#" onfocus="this.blur()">Lien</a>

Ce qui ne va pas : Le script retire le focus (blur()) dès qu'il est reçu : l'utilisateur clavier ne peut jamais placer le focus sur ce lien, il « saute » sans pouvoir l'activer ni savoir où il se trouve. Un script ne doit pas supprimer le focus d'un élément qui le reçoit.

Comment corriger : Ne jamais supprimer le focus dans un gestionnaire d'événement. Si le composant doit être retiré de la tabulation, le faire proprement (suppression du DOM, ou tabindex="-1" pour un focus programmatique uniquement).

WCAG :
  • 1.3.1 Info and Relationships (A)
  • 2.1.1 Keyboard (A)
  • 2.4.7 Focus Visible (AA)

7.4 — Pour chaque script qui initie un changement de contexte, l'utilisateur est-il averti ou en a-t-il le contrôle ?

7.4.1 manuel

Chaque script qui initie un changement de contexte vérifie-t-il une de ces conditions ? L'utilisateur est averti par un texte de l'action du script et du type de changement avant son déclenchement ; Le changement de contexte est initié par un bouton (input de type submit, button ou image ou balise <button>) explicite ; Le changement de contexte est initié par un lien explicite.

Démo volontairement fautive

Voir le code source du piège
<label for="f-7-4-1-nav">Choisir une page</label> <select id="f-7-4-1-nav" onchange="location.href='page2.html'"><option>Accueil</option><option>Contact</option></select>

Ce qui ne va pas : La simple sélection d'une option déclenche une navigation (changement de contexte) sans avertissement préalable : l'utilisateur est déplacé vers une autre page alors qu'il pensait seulement choisir une valeur. Le changement de contexte doit être initié par un bouton ou un lien explicite, ou annoncé à l'avance.

Comment corriger : Déclencher le changement de contexte uniquement via un bouton explicite (par ex. un bouton « Aller ») ou prévenir l'utilisateur par un texte avant l'action.

WCAG :
  • 3.2.1 On Focus (A)
  • 3.2.2 On Input (A)

7.5 — Dans chaque page web, les messages de statut sont-ils correctement restitués par les technologies d'assistance ?

7.5.1 manuel

Chaque message de statut qui informe de la réussite, du résultat d'une action ou bien de l'état d'une application utilise-t-il l'attribut WAI-ARIA role="status" ?

Démo volontairement fautive

Votre message a bien été envoyé.

Voir le code source du piège
<p>Votre message a bien été envoyé.</p>

Ce qui ne va pas : Ce message de statut annonce la réussite d'une action mais n'utilise pas role="status" : les technologies d'assistance ne sont pas notifiées de son apparition, l'utilisateur peut ne jamais l'entendre.

Comment corriger : Ajouter role="status" (région live polie) : <p role="status">Votre message a bien été envoyé.</p>, afin que le message soit annoncé sans interrompre la lecture en cours.

WCAG :
  • 4.1.3 Status Messages (AA)

7.5.2 manuel

Chaque message de statut qui présente une suggestion, ou avertit de l'existence d'une erreur utilise-t-il l'attribut WAI-ARIA role="alert" ?

Démo volontairement fautive

Le mot de passe saisi est incorrect.

Voir le code source du piège
<p>Le mot de passe saisi est incorrect.</p>

Ce qui ne va pas : Ce message avertit d'une erreur de saisie mais n'utilise pas role="alert" : il n'est pas annoncé immédiatement par les technologies d'assistance, l'utilisateur ignore qu'une correction est nécessaire.

Comment corriger : Ajouter role="alert" (région live assertive) : <p role="alert">Le mot de passe saisi est incorrect.</p>.

WCAG :
  • 4.1.3 Status Messages (AA)

7.5.3 manuel

Chaque message de statut qui indique la progression d'un processus utilise-t-il l'un des attributs WAI-ARIA role="log", role="progressbar" ou role="status" ?

Démo volontairement fautive

Téléchargement en cours : 50 %.

Voir le code source du piège
<p>Téléchargement en cours : 50 %.</p>

Ce qui ne va pas : Ce message indique la progression d'un processus mais n'utilise aucun des rôles attendus (log, progressbar, status) : sa mise à jour n'est pas annoncée aux technologies d'assistance.

Comment corriger : Utiliser role="progressbar" avec aria-valuenow/aria-valuemin/aria-valuemax, ou role="log"/role="status" pour un suivi textuel de la progression.

WCAG :
  • 4.1.3 Status Messages (AA)

8. Éléments obligatoires (13 tests)

Éléments obligatoires de toute page : doctype, langue, titre, validité du code, sens de lecture.

8.1 — Chaque page web est-elle définie par un type de document ?

8.1.1 n/a

Pour chaque page web, le type de document (balise doctype) est-il présent ?

Démo volontairement fautive

Non démontrable en page statique — voir l'explication ci-dessous.

Ce qui ne va pas : Le test porte sur la page entière : la présence du <!DOCTYPE html> se vérifie tout en haut du code source, avant <html>. La page benchmark est elle-même conforme (doctype présent) ; sur une page cible, l'absence de doctype fait basculer le navigateur en mode quirks et casse le rendu et l'interprétation du HTML.

Comment corriger : Sur la page cible, vérifier que la première ligne du code source est <!DOCTYPE html> (ou un autre doctype valide).

WCAG :
  • 4.1.1 Parsing (A)

8.1.2 n/a

Pour chaque page web, le type de document (balise doctype) est-il valide ?

Démo volontairement fautive

Non démontrable en page statique — voir l'explication ci-dessous.

Ce qui ne va pas : Le test porte sur la page entière : il vérifie que le doctype déclaré est valide. La page benchmark est conforme ; sur une page cible, un doctype invalide (coquille dans la déclaration, doctype obsolète ou non conforme au document) empêche le navigateur de choisir le bon mode de rendu.

Comment corriger : Sur la page cible, utiliser un doctype conforme au type de document choisi, par exemple <!DOCTYPE html> pour HTML5, en tête de fichier.

WCAG :
  • 4.1.1 Parsing (A)

8.1.3 n/a

Pour chaque page web possédant une déclaration de type de document, celle-ci est-elle située avant la balise <html> dans le code source ?

Démo volontairement fautive

Non démontrable en page statique — voir l'explication ci-dessous.

Ce qui ne va pas : Le test porte sur la page entière : le doctype doit être situé avant la balise <html>. La page benchmark est conforme ; sur une page cible, un doctype placé après <html> (ou après du texte ou des commentaires) est ignoré et le document bascule en mode quirks.

Comment corriger : Sur la page cible, s'assurer que <!DOCTYPE html> est la toute première chose du fichier, avant <html> et avant tout commentaire.

WCAG :
  • 4.1.1 Parsing (A)

8.2 — Pour chaque page web, le code source généré est-il valide selon le type de document spécifié ?

8.2.1 partiel

Pour chaque déclaration de type de document, le code source généré de la page vérifie-t-il ces conditions ? Les balises, attributs et valeurs d'attributs respectent les règles d'écriture ; L'imbrication des balises est conforme ; L'ouverture et la fermeture des balises sont conformes ; Les valeurs d'attribut id sont uniques dans la page ; Les attributs ne sont pas doublés sur un même élément.

Démo volontairement fautive

Description du service

Doublon de l'identifiant

Voir le code source du piège
<button aria-describedby="f-8-2-1-desc">Plus d'infos</button><p id="f-8-2-1-desc">Description du service</p><p id="f-8-2-1-desc">Doublon de l'identifiant</p>

Ce qui ne va pas : Le test 8.2.1 vérifie la validité du code source, dont l'unicité des id. Ici, deux éléments portent le même id (f-8-2-1-desc), et cet identifiant est référencé par aria-describedby : les technologies d'assistance ne savent plus quelle description associer. axe-core signale un doute (incomplete) : la confirmation humaine est nécessaire.

Comment corriger : Rendre chaque id unique dans la page (f-8-2-1-desc et f-8-2-1-desc-2) et vérifier avec un validateur HTML les autres conditions (imbrication, fermeture, attributs non doublés).

WCAG :
  • 4.1.1 Parsing (A)
  • 4.1.2 Name, Role, Value (A)

8.3 — Dans chaque page web, la langue par défaut est-elle présente ?

8.3.1 axe · valid-lang

Pour chaque page web, l'indication de langue par défaut vérifie-t-elle une de ces conditions ? L'indication de la langue de la page (attribut lang et/ou xml:lang) est donnée pour l'élément html ; L'indication de la langue de la page (attribut lang et/ou xml:lang) est donnée sur chaque élément de texte ou sur l'un des éléments parents.

Démo volontairement fautive

Bienvenue sur le site.

Voir le code source du piège
<p lang="xx">Bienvenue sur le site.</p>

Ce qui ne va pas : La langue par défaut d'une page doit être indiquée sur l'élément <html> (ou sur chaque élément de texte ou parent). La page benchmark déclare lang="fr" sur <html> et est conforme ; le fragment ci-dessous illustre le défaut sur une page cible : l'indication de langue portée par un élément de texte utilise un code invalide (xx n'est pas un code BCP 47), la langue reste donc indéterminée pour les technologies d'assistance.

Comment corriger : Sur la page cible, vérifier la présence de lang="fr" (ou d'un code pertinent) sur <html>, ou sur chaque élément de texte ou parent, avec un code de langue valide.

WCAG :
  • 3.1.1 Language of Page (A)

8.4 — Pour chaque page web ayant une langue par défaut, le code de langue est-il pertinent ?

8.4.1 axe · valid-lang

Pour chaque page web ayant une langue par défaut, le code de langue vérifie-t-il ces conditions ? Le code de langue est valide ; Le code de langue est pertinent.

Démo volontairement fautive

Ce texte est en français mais déclare une langue inconnue.

Voir le code source du piège
<p lang="zz">Ce texte est en français mais déclare une langue inconnue.</p>

Ce qui ne va pas : Le code de langue déclaré (zz) n'est pas un code BCP 47 valide : la synthèse vocale ne peut pas choisir la bonne prononciation et le lecteur d'écran applique la langue par défaut. Le code doit en outre être pertinent, c'est-à-dire correspondre à la langue réelle du texte.

Comment corriger : Déclarer un code de langue valide et pertinent, par exemple lang="fr" pour du français, sur l'élément <html> ou sur les éléments concernés.

WCAG :
  • 3.1.1 Language of Page (A)

8.5 — Chaque page web a-t-elle un titre de page ?

8.5.1 n/a

Chaque page web a-t-elle un titre de page (balise <title>) ?

Démo volontairement fautive

Non démontrable en page statique — voir l'explication ci-dessous.

Ce qui ne va pas : Le test porte sur la page entière : chaque page doit avoir une balise <title> dans son <head>. La page benchmark possède un titre et est conforme ; sur une page cible, l'absence de <title> affiche le nom du fichier dans l'onglet et rend l'identification de la page impossible pour les lecteurs d'écran.

Comment corriger : Sur la page cible, vérifier la présence d'une balise <title> non vide dans le <head> de chaque page.

WCAG :
  • 2.4.2 Page Titled (A)

8.6 — Pour chaque page web ayant un titre de page, ce titre est-il pertinent ?

8.6.1 n/a

Pour chaque page web ayant un titre de page (balise <title>), le contenu de cette balise est-il pertinent ?

Démo volontairement fautive

Non démontrable en page statique — voir l'explication ci-dessous.

Ce qui ne va pas : Le test porte sur la page entière : le contenu de la balise <title> doit être pertinent, c'est-à-dire identifier clairement la page et son site. La page benchmark est conforme ; sur une page cible, un titre vide, générique (« Accueil », « Document sans titre ») ou identique sur toutes les pages est considéré non pertinent.

Comment corriger : Sur la page cible, rédiger un titre unique et descriptif par page (par ex. « Contact — Services Publics »), y compris quand la page change de contenu via script.

WCAG :
  • 2.4.2 Page Titled (A)

8.7 — Dans chaque page web, chaque changement de langue est-il indiqué dans le code source (hors cas particuliers) ?

8.7.1 manuel

Dans chaque page web, chaque texte écrit dans une langue différente de la langue par défaut vérifie-t-il une de ces conditions (hors cas particuliers) ? L'indication de langue est donnée sur l'élément contenant le texte (attribut lang et/ou xml:lang) ; L'indication de langue est donnée sur un des éléments parents (attribut lang et/ou xml:lang).

Démo volontairement fautive

Pour continuer, cliquez sur Sign in.

Voir le code source du piège
<p>Pour continuer, cliquez sur <span>Sign in</span>.</p>

Ce qui ne va pas : Le passage « Sign in » est écrit en anglais alors que la langue par défaut de la page est le français, et aucune indication de langue (lang="en") n'est portée par l'élément ou un parent. La synthèse vocale prononce le mot anglais avec la phonétique française.

Comment corriger : Indiquer le changement de langue sur l'élément concerné : <span lang="en">Sign in</span>, et ce pour chaque passage dans une autre langue.

WCAG :
  • 3.1.2 Language of Parts (AA)

8.8 — Dans chaque page web, le code de langue de chaque changement de langue est-il valide et pertinent ?

8.8.1 axe · valid-lang

Pour chaque page web, le code de langue de chaque changement de langue vérifie-t-il ces conditions ? Le code de langue est valide ; Le code de langue est pertinent.

Démo volontairement fautive

Cliquez sur welcome pour démarrer.

Voir le code source du piège
<p>Cliquez sur <span lang="zz">welcome</span> pour démarrer.</p>

Ce qui ne va pas : Le changement de langue est indiqué mais son code (zz) n'est pas un code BCP 47 valide : l'indication est inutilisable par les technologies d'assistance. Le code doit être à la fois valide et pertinent (correspondre réellement à la langue du texte).

Comment corriger : Utiliser un code valide et pertinent, par exemple <span lang="en">welcome</span> pour du texte anglais dans une page française.

WCAG :
  • 3.1.2 Language of Parts (AA)

8.9 — Dans chaque page web, les balises ne doivent pas être utilisées uniquement à des fins de présentation. Cette règle est-elle respectée ?

8.9.1 manuel

Dans chaque page web les balises (à l'exception de <div>, <span> et <table>) ne doivent pas être utilisées uniquement à des fins de présentation. Cette règle est-elle respectée ?

Démo volontairement fautive

Ce bloc est simplement indenté : ce n'est pas une citation.
Voir le code source du piège
<blockquote style="margin-left:2em;">Ce bloc est simplement indenté : ce n'est pas une citation.</blockquote>

Ce qui ne va pas : Les balises (autres que <div>, <span> et <table>) ne doivent pas être détournées à des fins de présentation. Ici, <blockquote> sert uniquement à indenter un texte qui n'est pas une citation : sa signification sémantique est fausse pour les technologies d'assistance.

Comment corriger : Utiliser une feuille de styles pour l'indentation : <p style="margin-left:2em;">…</p>, et réserver <blockquote> aux véritables blocs de citation.

WCAG :
  • 1.3.1 Info and Relationships (A)

8.10 — Dans chaque page web, les changements du sens de lecture sont-ils signalés ?

8.10.1 manuel

Dans chaque page web, chaque texte dont le sens de lecture est différent du sens de lecture par défaut est contenu dans une balise possédant un attribut dir ?

Démo volontairement fautive

Le mot hébreu שלום signifie « bonjour ».

Voir le code source du piège
<p>Le mot hébreu <span>שלום</span> signifie « bonjour ».</p>

Ce qui ne va pas : Ce passage en hébreu a un sens de lecture différent (droite à gauche) mais aucun attribut dir ne le signale : le navigateur et les technologies d'assistance l'affichent et le lisent dans le mauvais sens.

Comment corriger : Ajouter dir="rtl" sur l'élément contenant le texte de droite à gauche : <span dir="rtl">שלום</span>, et dir="ltr" pour un retour au sens normal.

WCAG :
  • 1.3.2 Meaningful Sequence (A)

8.10.2 manuel

Dans chaque page web, chaque changement du sens de lecture (attribut dir) vérifie-t-il ces conditions ? La valeur de l'attribut dir est conforme (rtl ou ltr) ; La valeur de l'attribut dir est pertinente.

Démo volontairement fautive

Texte français avec un attribut dir invalide.

Voir le code source du piège
<p dir="sideways">Texte français avec un attribut dir invalide.</p>

Ce qui ne va pas : L'attribut dir n'accepte que les valeurs rtl ou ltr (et auto pour la détection automatique) : la valeur sideways est invalide et l'indication est ignorée. La valeur doit en outre être pertinente, c'est-à-dire correspondre au sens de lecture réel du texte.

Comment corriger : Remplacer par une valeur conforme : dir="rtl" pour un texte de droite à gauche, dir="ltr" sinon, et vérifier que le sens indiqué correspond au contenu.

WCAG :
  • 1.3.2 Meaningful Sequence (A)

9. Structuration de l'information (9 tests)

Structuration de l'information : hiérarchie des titres, zones de page, listes, citations.

9.1 — Dans chaque page web, l'information est-elle structurée par l'utilisation appropriée de titres ?

9.1.1 collecteur · heading-order

Dans chaque page web, la hiérarchie entre les titres (balise <hx> ou balise possédant un attribut WAI-ARIA role="heading" associé à un attribut WAI-ARIA aria-level) est-elle pertinente ?

Démo volontairement fautive

Section principale

Sous-section

Voir le code source du piège
<h2>Section principale</h2><h4>Sous-section</h4>

Ce qui ne va pas : La hiérarchie des titres saute un niveau : on passe de <h2> à <h4> sans <h3> intermédiaire. Les utilisateurs de lecteurs d'écran qui naviguent par titres ne comprennent plus la structure du document.

Comment corriger : Respecter une progression d'un niveau à la fois : <h2> puis <h3> puis <h4>, et ne revenir à un niveau supérieur qu'à la fin de la section (un <h4> ne suit un <h2> que s'il est dans un <h3>).

WCAG :
  • 1.3.1 Info and Relationships (A)
  • 2.4.1 Bypass Blocks (A)
  • 2.4.6 Headings and Labels (AA)
  • 4.1.2 Name, Role, Value (A)

9.1.2 manuel

Dans chaque page web, le contenu de chaque titre (balise <hx> ou balise possédant un attribut WAI-ARIA role="heading" associé à un attribut WAI-ARIA aria-level) est-il pertinent ?

Démo volontairement fautive

Cliquez ici

Voir le code source du piège
<h2>Cliquez ici</h2>

Ce qui ne va pas : Le contenu de ce titre n'est pas pertinent : « Cliquez ici » n'identifie pas la section qu'il introduit. Un titre doit décrire le contenu qui suit pour être utile à la navigation par titres.

Comment corriger : Rédiger un intitulé descriptif du contenu de la section, par exemple <h2>Comment créer un compte</h2>.

WCAG :
  • 1.3.1 Info and Relationships (A)
  • 2.4.1 Bypass Blocks (A)
  • 2.4.6 Headings and Labels (AA)
  • 4.1.2 Name, Role, Value (A)

9.1.3 manuel

Dans chaque page web, chaque passage de texte constituant un titre est-il structuré à l'aide d'une balise <hx> ou d'une balise possédant un attribut WAI-ARIA role="heading" associé à un attribut WAI-ARIA aria-level ?

Démo volontairement fautive

Titre de section

Voir le code source du piège
<p style="font-size:32px;font-weight:bold;">Titre de section</p>

Ce qui ne va pas : Ce passage de texte est visuellement un titre (grand et gras) mais il est balisé <p> : les technologies d'assistance ne l'exposent pas comme titre, la structure est perdue. La règle axe p-as-heading existe mais elle est expérimentale et n'est pas exécutée par ally-agent : contrôle manuel.

Comment corriger : Structurer le passage avec une vraie balise de titre : <h2>Titre de section</h2>, en respectant la hiérarchie.

WCAG :
  • 1.3.1 Info and Relationships (A)
  • 2.4.1 Bypass Blocks (A)
  • 2.4.6 Headings and Labels (AA)
  • 4.1.2 Name, Role, Value (A)

9.2 — Dans chaque page web, la structure du document est-elle cohérente (hors cas particuliers) ?

9.2.1 partiel

Dans chaque page web, la structure du document vérifie-t-elle ces conditions (hors cas particuliers) ? La zone d'en-tête de la page est structurée via une balise <header> ; Les zones de navigation principale et secondaire sont structurées via une balise <nav> ; La balise <nav> est réservée à la structuration des zones de navigation principales et secondaires ; La zone de contenu principal est structurée via une balise <main> ; La structure du document utilise une balise <main> visible unique ; La zone de pied de page est structurée via une balise <footer>.

Démo volontairement fautive

En-tête du site
Contenu principal
Pied de page
Voir le code source du piège
<div class="entete">En-tête du site</div><div class="menu"><a href="#">Accueil</a></div><div class="contenu">Contenu principal</div><div class="pied">Pied de page</div>

Ce qui ne va pas : L'en-tête, la navigation, le contenu principal et le pied de page sont des <div> : aucune des balises de structure (<header>, <nav>, <main>, <footer>) n'est utilisée. Les utilisateurs de technologies d'assistance ne peuvent pas accéder directement à ces zones.

Comment corriger : Utiliser les balises sémantiques : <header> pour l'en-tête, <nav> pour la navigation (et rien d'autre), un <main> unique et visible pour le contenu, <footer> pour le pied de page.

WCAG :
  • 1.3.1 Info and Relationships (A)

9.3 — Dans chaque page web, chaque liste est-elle correctement structurée ?

9.3.1 axe · list

Dans chaque page web, les informations regroupées visuellement sous forme de liste non ordonnée vérifient-elles une de ces conditions ? La liste utilise les balises HTML <ul> et <li> ; La liste utilise les attributs WAI-ARIA role="list" et role="listitem".

Démo volontairement fautive

    Premier élémentDeuxième élément
Voir le code source du piège
<ul><span>Premier élément</span><span>Deuxième élément</span></ul>

Ce qui ne va pas : La liste non ordonnée <ul> contient des <span> au lieu d'éléments <li> : la structure de liste est invalide et le nombre d'éléments n'est pas restitué par les technologies d'assistance.

Comment corriger : Envelopper chaque élément dans <li> : <ul><li>Premier élément</li><li>Deuxième élément</li></ul>.

WCAG :
  • 1.3.1 Info and Relationships (A)

9.3.2 axe · list

Dans chaque page web, les informations regroupées visuellement sous forme de liste ordonnée vérifient-elles une de ces conditions ? La liste utilise les balises HTML <ol> et <li> ; La liste utilise les attributs WAI-ARIA role="list" et role="listitem".

Démo volontairement fautive

    Étape 1
    Étape 2
Voir le code source du piège
<ol><div>Étape 1</div><div>Étape 2</div></ol>

Ce qui ne va pas : La liste ordonnée <ol> contient des <div> au lieu d'éléments <li> : la structure est invalide et la numérotation implicite (1, 2…) n'est pas exposée aux technologies d'assistance.

Comment corriger : Utiliser des <li> : <ol><li>Étape 1</li><li>Étape 2</li></ol>.

WCAG :
  • 1.3.1 Info and Relationships (A)

9.3.3 axe · definition-list

Dans chaque page web, les informations regroupées sous forme de liste de description utilisent-elles les balises <dl> et <dt>/<dd> ?

Démo volontairement fautive

Réseau

Ensemble de machines interconnectées.

Voir le code source du piège
<dl><p>Réseau</p><p>Ensemble de machines interconnectées.</p></dl>

Ce qui ne va pas : La liste de description <dl> doit contenir des <dt> (termes) et des <dd> (descriptions) : ici ce sont des <p>, la structure terme/définition n'est pas restituée.

Comment corriger : Structurer avec <dt>/<dd> : <dl><dt>Réseau</dt><dd>Ensemble de machines interconnectées.</dd></dl>.

WCAG :
  • 1.3.1 Info and Relationships (A)

9.4 — Dans chaque page web, chaque citation est-elle correctement indiquée ?

9.4.1 manuel

Dans chaque page web, chaque citation courte utilise-t-elle une balise <q> ?

Démo volontairement fautive

Il a dit : « La formation est essentielle. »

Voir le code source du piège
<p>Il a dit : « La formation est essentielle. »</p>

Ce qui ne va pas : Cette citation courte est indiquée par des guillemets typographiques mais pas par la balise <q> : la nature de citation n'est pas restituée par les technologies d'assistance.

Comment corriger : Baliser la citation : <p>Il a dit : <q>La formation est essentielle.</q></p>.

WCAG :
  • 1.3.1 Info and Relationships (A)

9.4.2 manuel

Dans chaque page web, chaque bloc de citation utilise-t-il une balise <blockquote> ?

Démo volontairement fautive

Longue citation qui devrait être un bloc de citation…
Voir le code source du piège
<div style="margin-left:2em;">Longue citation qui devrait être un bloc de citation…</div>

Ce qui ne va pas : Ce bloc de citation est un <div> simplement indenté : il n'est pas balisé <blockquote> et sa nature de citation n'est pas exposée aux technologies d'assistance.

Comment corriger : Utiliser <blockquote> : <blockquote>Longue citation…</blockquote>.

WCAG :
  • 1.3.1 Info and Relationships (A)

10. Présentation de l'information (29 tests)

Présentation : les feuilles de style ne doivent pas faire perdre l'information (contraste, redimensionnement, focus visible, contenus additionnels).

10.1 — Dans le site web, des feuilles de styles sont-elles utilisées pour contrôler la présentation de l'information ?

10.1.1 manuel

Dans chaque page web, les balises servant à la présentation de l'information ne doivent pas être présentes dans le code source généré des pages. Cette règle est-elle respectée ?

Démo volontairement fautive

Texte en rouge.

Voir le code source du piège
<p><font color="#c00">Texte en rouge.</font></p>

Ce qui ne va pas : La balise <font> est une balise de présentation : la mise en forme doit être assurée par les feuilles de styles. Ces balises anciennes (font, center, big, u…) n'ont aucune sémantique et perturbent la restitution.

Comment corriger : Remplacer par du CSS : <p style="color:#c00;">Texte en rouge.</p>.

WCAG :
  • 1.3.1 Info and Relationships (A)
  • 1.3.2 Meaningful Sequence (A)

10.1.2 manuel

Dans chaque page web, les attributs servant à la présentation de l'information ne doivent pas être présents dans le code source généré des pages. Cette règle est-elle respectée ?

Démo volontairement fautive

Paragraphe centré par attribut.

Voir le code source du piège
<p align="center">Paragraphe centré par attribut.</p>

Ce qui ne va pas : L'attribut align est un attribut de présentation : la mise en forme est dans le HTML au lieu d'être dans les feuilles de styles. D'autres attributs du même type (bgcolor, border, width…) sont également concernés.

Comment corriger : Remplacer par du CSS : <p style="text-align:center;">Paragraphe centré.</p>.

WCAG :
  • 1.3.1 Info and Relationships (A)
  • 1.3.2 Meaningful Sequence (A)

10.1.3 manuel

Dans chaque page web, l'utilisation des espaces vérifie-t-elle ces conditions ? Les espaces ne sont pas utilisées pour séparer les lettres d'un mot ; Les espaces ne sont pas utilisées pour simuler des tableaux ; Les espaces ne sont pas utilisées pour simuler des colonnes de texte.

Démo volontairement fautive

S E R V I C E S

Voir le code source du piège
<p>S E R V I C E S</p>

Ce qui ne va pas : Les espaces sont ici utilisées pour séparer les lettres d'un mot afin de simuler un espacement typographique. Les lecteurs d'écran peuvent lire chaque lettre séparément et les espaces multiples cassent le contenu ; les espaces ne doivent jamais servir à simuler un rendu (lettres espacées, tableaux, colonnes de texte).

Comment corriger : Utiliser CSS pour l'espacement des lettres : letter-spacing, et des tableaux ou grilles CSS pour aligner des colonnes.

WCAG :
  • 1.3.1 Info and Relationships (A)
  • 1.3.2 Meaningful Sequence (A)

10.2 — Dans chaque page web, le contenu visible porteur d’information reste-t-il présent lorsque les feuilles de styles sont désactivées ?

10.2.1 manuel

Dans chaque page web, l'information reste-t-elle présente lorsque les feuilles de styles sont désactivées ?

Démo volontairement fautive

Voir le code source du piège
<div style="background:url(img/info.png) no-repeat;width:120px;height:80px;"></div>

Ce qui ne va pas : L'information est portée uniquement par une image de fond CSS : sans les feuilles de styles, l'image et l'information disparaissent, et les technologies d'assistance ne la restituent jamais. Le contenu visible porteur d'information doit rester présent lorsque les styles sont désactivés.

Comment corriger : Intégrer l'information dans le contenu : une balise <img src="img/info.png" alt="…"> avec une alternative pertinente, ou du texte, plutôt qu'un fond CSS.

WCAG :
  • 1.1.1 Non-text Content (A)
  • 1.3.1 Info and Relationships (A)

10.3 — Dans chaque page web, l'information reste-t-elle compréhensible lorsque les feuilles de styles sont désactivées ?

10.3.1 manuel

Dans chaque page web, l'information reste-t-elle compréhensible lorsque les feuilles de styles sont désactivées ?

Démo volontairement fautive

Premier paragraphe dans le code source.

Deuxième paragraphe affiché au-dessus.

Voir le code source du piège
<p>Premier paragraphe dans le code source.</p><p style="position:absolute;top:0;left:260px;width:200px;">Deuxième paragraphe affiché au-dessus.</p>

Ce qui ne va pas : Le positionnement CSS absolu affiche le deuxième paragraphe au-dessus du premier alors que l'ordre du code source est l'inverse : l'ordre de lecture (DOM) ne correspond plus à l'ordre visuel, ce qui désoriente les utilisateurs de technologies d'assistance.

Comment corriger : Faire correspondre l'ordre visuel et l'ordre du code source ; si l'ordre visuel diffère, restructurer le DOM plutôt que de jouer sur le positionnement.

WCAG :
  • 1.3.2 Meaningful Sequence (A)
  • 2.4.3 Focus Order (A)

10.4 — Dans chaque page web, le texte reste-t-il lisible lorsque la taille des caractères est augmentée jusqu'à 200%, au moins (hors cas particuliers) ?

10.4.1 manuel

Dans chaque page web, l'augmentation de la taille des caractères jusqu'à 200%, au moins, ne doit pas provoquer de perte d'information. Cette règle est-elle respectée selon une de ces conditions (hors cas particuliers) ? Lors de l'utilisation de la fonction d'agrandissement du texte du navigateur ; Lors de l'utilisation des fonctions de zoom graphique du navigateur ; Lors de l'utilisation d'un composant d'interface propre au site permettant d'agrandir le texte ou de zoomer.

Démo volontairement fautive

Ce texte volontairement long est tronqué lorsque le zoom atteint 200 %.
Voir le code source du piège
<div style="width:140px;overflow:hidden;white-space:nowrap;">Ce texte volontairement long est tronqué lorsque le zoom atteint 200 %.</div>

Ce qui ne va pas : Ce bloc a une largeur fixe, white-space:nowrap et overflow:hidden : à 200 % de zoom, le texte est coupé et une partie de l'information devient inaccessible sans défilement possible.

Comment corriger : Laisser le texte se réorganiser : supprimer nowrap et overflow:hidden, utiliser des largeurs relatives et des conteneurs fluides.

WCAG :
  • 1.4.4 Resize Text (AA)

10.4.2 manuel

Dans chaque page web, l'augmentation de la taille des caractères jusqu'à 200%, au moins, doit être possible pour l’ensemble du texte dans la page. Cette règle est-elle respectée selon une de ces conditions (hors cas particuliers) ? Lors de l'utilisation de la fonction d'agrandissement du texte du navigateur ; Lors de l'utilisation des fonctions de zoom graphique du navigateur ; Lors de l'utilisation d'un composant d'interface propre au site permettant d'agrandir le texte ou de zoomer.

Démo volontairement fautive

Corps de texte en taille fixe en pixels.

Voir le code source du piège
<p style="font-size:12px;">Corps de texte en taille fixe en pixels.</p>

Ce qui ne va pas : La taille du texte est fixée en pixels sur l'ensemble du contenu : la fonction d'agrandissement du texte du navigateur ne peut pas l'augmenter dans certains navigateurs, et le site n'offre aucun composant d'agrandissement. Tout le texte doit pouvoir être agrandi jusqu'à 200 %.

Comment corriger : Utiliser des unités relatives (em, rem, %) pour les tailles de police afin que l'agrandissement du texte fonctionne partout.

WCAG :
  • 1.4.4 Resize Text (AA)

10.5 — Dans chaque page web, les déclarations CSS de couleurs de fond d'élément et de police sont-elles correctement utilisées ?

10.5.1 partiel

Dans chaque page web, chaque déclaration CSS de couleurs de police (color), d'un élément susceptible de contenir du texte, est-elle accompagnée d'une déclaration de couleur de fond (background, background-color), au moins, héritée d'un parent ?

Démo volontairement fautive

Texte blanc sans couleur de fond déclarée.

Voir le code source du piège
<p style="color:#fff;">Texte blanc sans couleur de fond déclarée.</p>

Ce qui ne va pas : La couleur de police est déclarée sans couleur de fond (ni sur l'élément, ni héritée d'un parent fiable) : sur le fond clair de la page, le texte blanc devient illisible. axe-core ne peut pas calculer le contraste sans fond résolu (résultat incomplete) : confirmation humaine nécessaire.

Comment corriger : Déclarer ensemble couleur de police et couleur de fond cohérentes : par exemple style="color:#fff;background:#333;", et vérifier le contraste (4,5:1 minimum).

WCAG :
  • 1.4.3 Contrast (Minimum) (AA)

10.5.2 axe · color-contrast

Dans chaque page web, chaque déclaration de couleur de fond (background, background-color), d'un élément susceptible de contenir du texte, est-elle accompagnée d'une déclaration de couleur de police (color) au moins, héritée d'un parent ?

Démo volontairement fautive

Texte sur fond noir sans couleur de police déclarée.

Voir le code source du piège
<p style="background:#000;">Texte sur fond noir sans couleur de police déclarée.</p>

Ce qui ne va pas : La couleur de fond est déclarée sans couleur de police sur l'élément : le texte hérite de la couleur par défaut de la page (sombre), quasiment invisible sur fond noir. Le contraste est insuffisant.

Comment corriger : Déclarer une couleur de police adaptée au fond : style="background:#000;color:#fff;", et vérifier le contraste.

WCAG :
  • 1.4.3 Contrast (Minimum) (AA)

10.5.3 partiel

Dans chaque page web, chaque utilisation d'une image pour créer une couleur de fond d'un élément susceptible de contenir du texte, via CSS (background, background-image), est-elle accompagnée d'une déclaration de couleur de fond (background, background-color), au moins, héritée d'un parent ?

Démo volontairement fautive

Texte posé sur une image de fond.

Voir le code source du piège
<p style="background-image:url(img/deco.png);">Texte posé sur une image de fond.</p>

Ce qui ne va pas : Une image de fond (background-image) est utilisée sans couleur de fond de secours : si l'image ne se charge pas ou est trop claire, le texte devient illisible. Le contraste effectif dépend de l'image et ne peut pas être calculé automatiquement.

Comment corriger : Toujours associer une couleur de fond de secours : style="background:url(img/deco.png) #eee;", puis vérifier manuellement le contraste du texte sur l'image.

WCAG :
  • 1.4.3 Contrast (Minimum) (AA)

10.6 — Dans chaque page web, chaque lien dont la nature n'est pas évidente est-il visible par rapport au texte environnant ?

10.6.1 axe · link-in-text-block

Dans chaque page web, chaque lien texte signalé uniquement par la couleur, et dont la nature n'est pas évidente, vérifie-t-il ces conditions ? La couleur du lien a un rapport de contraste supérieur ou égal à 3:1 par rapport au texte environnant ; Le lien dispose d'une indication visuelle au survol autre qu'un changement de couleur ; Le lien dispose d'une indication visuelle au focus autre qu'un changement de couleur.

Démo volontairement fautive

Texte environnant lien discret dans le même paragraphe.

Voir le code source du piège
<p style="color:#222;">Texte environnant <a href="#" style="color:#444;text-decoration:none;">lien discret</a> dans le même paragraphe.</p>

Ce qui ne va pas : Ce lien n'est distingué du texte environnant que par une nuance de couleur (contraste d'environ 1,8:1, bien sous le seuil de 3:1) : sans soulignement ni autre indice, il est invisible pour beaucoup d'utilisateurs. La règle axe link-in-text-block le détecte.

Comment corriger : Différencier le lien par un autre indice que la couleur : soulignement (text-decoration:underline), et garantir un contraste de 3:1 avec le texte environnant.

WCAG :
  • 1.4.1 Use of Color (A)

10.7 — Dans chaque page web, pour chaque élément recevant le focus, la prise de focus est-elle visible ?

10.7.1 manuel

Pour chaque élément recevant le focus, la prise de focus vérifie-t-elle une de ces conditions ? Le style du focus natif du navigateur n'est pas supprimé ou dégradé ; Un style du focus défini par l'auteur est visible.

Démo volontairement fautive

Voir le code source du piège
<a href="#" style="outline:none;">Lien sans indication de focus.</a>

Ce qui ne va pas : Le style de focus natif du navigateur (outline) est supprimé sans être remplacé par un style de focus défini par l'auteur : un utilisateur clavier ne voit plus où se trouve le focus et se perd dans la navigation.

Comment corriger : Ne pas supprimer l'outline sans la remplacer : par exemple a:focus { outline: 2px solid #005fcc; } pour garder une prise de focus visible.

WCAG :
  • 1.4.1 Use of Color (A)
  • 2.4.7 Focus Visible (AA)

10.8 — Pour chaque page web, les contenus cachés ont-ils vocation à être ignorés par les technologies d'assistance ?

10.8.1 manuel

Dans chaque page web, chaque contenu caché vérifie-t-il une de ces conditions ? Le contenu caché a vocation à être ignoré par les technologies d'assistance ; Le contenu caché n’a pas vocation à être ignoré par les technologies d’assistance et est rendu restituable par les technologies d'assistance suite à une action de l'utilisateur réalisable au clavier ou par tout dispositif de pointage sur un élément précédent le contenu caché ou suite à un repositionnement du focus dessus.

Démo volontairement fautive

Message important : le service sera indisponible dimanche.

Voir le code source du piège
<p style="display:none;">Message important : le service sera indisponible dimanche.</p>

Ce qui ne va pas : Ce contenu caché par display:none est retiré de l'arbre d'accessibilité alors qu'il a vocation à être lu (information importante pour tous). Un contenu caché doit être réellement ignorable (décoratif, aria-hidden) ou restituable suite à une action de l'utilisateur (clavier ou pointage).

Comment corriger : Si l'information doit être connue de tous, l'afficher ; si elle n'apparaît que dans certaines conditions, la rendre restituable après une action (par ex. un bouton qui révèle le message) ou la marquer aria-hidden="true" si elle est purement décorative.

WCAG :
  • 1.3.2 Meaningful Sequence (A)
  • 4.1.2 Name, Role, Value (A)

10.9 — Dans chaque page web, l'information ne doit pas être donnée uniquement par la forme, taille ou position. Cette règle est-elle respectée ?

10.9.1 manuel

Dans chaque page web, pour chaque texte ou ensemble de textes, l'information ne doit pas être donnée uniquement par la forme, taille ou position. Cette règle est-elle respectée ?

Démo volontairement fautive

Pour valider, cliquez sur le bouton rond situé à droite du champ de saisie.

Voir le code source du piège
<p>Pour valider, cliquez sur le bouton rond situé à droite du champ de saisie.</p>

Ce qui ne va pas : L'information est donnée uniquement par la forme (« rond ») et la position (« à droite du champ ») : un utilisateur de lecteur d'écran ou une personne qui ne perçoit pas la mise en page ne peut pas identifier le bouton.

Comment corriger : Donner un repère textuel indépendant de la forme et de la position : par exemple « cliquez sur le bouton Envoyer ».

WCAG :
  • 1.3.3 Sensory Characteristics (A)
  • 1.4.1 Use of Color (A)

10.9.2 manuel

Dans chaque page web, pour chaque image ou ensemble d'images, l'information ne doit pas être donnée uniquement par la forme, taille ou position. Cette règle est-elle respectée ?

Démo volontairement fautive

L'image du haut est le nouveau logo, celle du bas l'ancien.

Nouveau logoAncien logo
Voir le code source du piège
<p>L'image du haut est le nouveau logo, celle du bas l'ancien.</p><img src="img/logo.png" width="100" height="40" alt="Nouveau logo"><img src="img/deco.png" width="80" height="40" alt="Ancien logo">

Ce qui ne va pas : L'information distingue les images par leur position (« du haut », « du bas ») : les technologies d'assistance ne restituent pas la position dans la page, l'information est perdue pour leurs utilisateurs.

Comment corriger : Désigner les images par leur alternative textuelle : « le logo Nouveau logo correspond au nouveau, le logo Ancien logo à l'ancien ».

WCAG :
  • 1.3.3 Sensory Characteristics (A)
  • 1.4.1 Use of Color (A)

10.9.3 manuel

Dans chaque page web, pour chaque média temporel, l'information ne doit pas être donnée uniquement par la forme, taille ou position. Cette règle est-elle respectée ?

Démo volontairement fautive

Comme indiqué au début de la vidéo, branchez d'abord le câble d'alimentation.

Voir le code source du piège
<p>Comme indiqué au début de la vidéo, branchez d'abord le câble d'alimentation.</p><video src="media/video.mp4" controls></video>

Ce qui ne va pas : L'information renvoie à un moment précis du média temporel (« au début de la vidéo ») : un utilisateur qui ne peut pas voir ou entendre la vidéo n'a aucun moyen d'accéder à cette information.

Comment corriger : Répéter l'information dans le texte environnant ou dans une alternative au média (transcription, sous-titres), sans référence à la position temporelle.

WCAG :
  • 1.3.3 Sensory Characteristics (A)
  • 1.4.1 Use of Color (A)

10.9.4 manuel

Dans chaque page web, pour chaque média non temporel, l'information ne doit pas être donnée uniquement par la forme, taille ou position. Cette règle est-elle respectée ?

Démo volontairement fautive

Le diagramme en bas à droite de la page résume les résultats.

Diagramme des résultats
Voir le code source du piège
<p>Le diagramme en bas à droite de la page résume les résultats.</p><img src="img/chart.png" width="160" height="100" alt="Diagramme des résultats">

Ce qui ne va pas : L'information désigne un média non temporel par sa position (« en bas à droite ») : la position n'est pas restituée par les technologies d'assistance et l'information n'est pas accessible.

Comment corriger : Référencer le média par son alternative textuelle ou son intitulé : « le Diagramme des résultats résume les chiffres ».

WCAG :
  • 1.3.3 Sensory Characteristics (A)
  • 1.4.1 Use of Color (A)

10.10 — Dans chaque page web, l'information ne doit pas être donnée par la forme, taille ou position uniquement. Cette règle est-elle implémentée de façon pertinente ?

10.10.1 manuel

Dans chaque page web, pour chaque texte ou ensemble de textes, l'information ne doit pas être donnée uniquement par la forme, taille ou position. Cette règle est-elle implémentée de façon pertinente ?

Démo volontairement fautive

Remplissez d'abord le champ du haut, puis validez.

Voir le code source du piège
<p>Remplissez d'abord le champ du haut, puis validez.</p>

Ce qui ne va pas : Une indication textuelle existe (« champ du haut ») mais elle n'est pas pertinente : elle repose encore sur la position, ambiguë si plusieurs champs sont alignés verticalement. L'implémentation de l'exemption doit être sans ambiguïté.

Comment corriger : Nommer les éléments par leur étiquette visible : « remplissez d'abord le champ Nom, puis validez ».

WCAG :
  • 1.3.3 Sensory Characteristics (A)
  • 1.4.1 Use of Color (A)

10.10.2 manuel

Dans chaque page web, pour chaque image ou ensemble d'images, l'information ne doit pas être donnée par la forme, taille ou position uniquement. Cette règle est-elle implémentée de façon pertinente ?

Démo volontairement fautive

Comparez l'image de droite avec celle de gauche.

Graphique des ventesGraphique des visites
Voir le code source du piège
<p>Comparez l'image de droite avec celle de gauche.</p><img src="img/chart.png" width="160" height="100" alt="Graphique des ventes"><img src="img/info.png" width="120" height="80" alt="Graphique des visites">

Ce qui ne va pas : Les images sont désignées par leur position (« de droite », « de gauche ») : l'indication n'est pas pertinente car la position n'est pas restituée par les technologies d'assistance et dépend de la taille d'écran.

Comment corriger : Désigner les images par leur alternative : « comparez le Graphique des ventes avec le Graphique des visites ».

WCAG :
  • 1.3.3 Sensory Characteristics (A)
  • 1.4.1 Use of Color (A)

10.10.3 manuel

Dans chaque page web, pour chaque média temporel, l'information ne doit pas être donnée par la forme, taille ou position uniquement. Cette règle est-elle implémentée de façon pertinente ?

Démo volontairement fautive

La réponse est annoncée à la fin de la vidéo.

Voir le code source du piège
<p>La réponse est annoncée à la fin de la vidéo.</p><video src="media/video.mp4" controls></video>

Ce qui ne va pas : L'indication renvoie à un instant du média (« à la fin de la vidéo ») : elle n'est pas pertinente pour un utilisateur qui ne peut pas visionner, et ne remplace pas une vraie alternative au contenu.

Comment corriger : Fournir une transcription ou un résumé textuel du média et y renvoyer explicitement, sans référence temporelle.

WCAG :
  • 1.3.3 Sensory Characteristics (A)
  • 1.4.1 Use of Color (A)

10.10.4 manuel

Dans chaque page web, pour chaque média non temporel, l'information ne doit pas être donnée par la forme, taille ou position uniquement. Cette règle est-elle implémentée de façon pertinente ?

Démo volontairement fautive

La réponse se trouve dans le schéma du milieu.

Schéma des résultats
Voir le code source du piège
<p>La réponse se trouve dans le schéma du milieu.</p><img src="img/chart.png" width="160" height="100" alt="Schéma des résultats">

Ce qui ne va pas : Le média non temporel est désigné par sa position (« du milieu ») : l'indication n'est pas pertinente, la position n'étant ni restituée ni stable selon le contexte d'affichage.

Comment corriger : Référencer le média par son alternative textuelle : « la réponse est dans le Schéma des résultats ».

WCAG :
  • 1.3.3 Sensory Characteristics (A)
  • 1.4.1 Use of Color (A)

10.11 — Pour chaque page web, les contenus peuvent-ils être présentés sans avoir recours à un défilement vertical pour une fenêtre ayant une hauteur de 256px ou à un défilement horizontal pour une fenêtre ayant une largeur de 320px (hors cas particuliers) ?

10.11.1 manuel

Pour chaque page web, lorsque le contenu dont le sens de lecture est horizontal est affiché dans une fenêtre réduite à une largeur de 320px, l'ensemble des informations et des fonctionnalités sont-elles disponibles sans aucun défilement horizontal (hors cas particuliers) ?

Démo volontairement fautive

Ce bloc de 600 px de large impose un défilement horizontal dans une fenêtre de 320 px.
Voir le code source du piège
<div style="width:600px;">Ce bloc de 600 px de large impose un défilement horizontal dans une fenêtre de 320 px.</div>

Ce qui ne va pas : Ce contenu a une largeur fixe de 600 px : dans une fenêtre réduite à 320 px, l'information n'est disponible qu'avec un défilement horizontal, interdit par le critère (hors cas particuliers).

Comment corriger : Utiliser des largeurs relatives et des mises en page fluides (max-width:100%, grilles adaptatives) pour que tout le contenu tienne dans 320 px sans défilement horizontal.

WCAG :
  • 1.4.10 Reflow (AA)

10.11.2 manuel

Pour chaque page web, lorsque le contenu dont le sens de lecture est vertical est affiché dans une fenêtre réduite à une hauteur de 256px, l'ensemble des informations et des fonctionnalités sont-elles disponibles sans aucun défilement vertical (hors cas particuliers) ?

Démo volontairement fautive

Texte en écriture verticale : la colonne de 400 px de haut impose un défilement vertical à 256 px.
Voir le code source du piège
<div style="writing-mode:vertical-rl;height:400px;">Texte en écriture verticale : la colonne de 400 px de haut impose un défilement vertical à 256 px.</div>

Ce qui ne va pas : Pour un contenu au sens de lecture vertical, la hauteur fixe de 400 px dépasse les 256 px autorisés : l'information nécessite un défilement vertical dans une fenêtre réduite.

Comment corriger : Laisser la hauteur s'adapter au contenu (supprimer la hauteur fixe et l'overflow) pour que tout reste visible dans 256 px de haut.

WCAG :
  • 1.4.10 Reflow (AA)

10.12 — Dans chaque page web, les propriétés d'espacement du texte peuvent-elles être redéfinies par l'utilisateur sans perte de contenu ou de fonctionnalité (hors cas particuliers) ?

10.12.1 manuel

Dans chaque page web, le texte reste-t-il lisible lorsque l'affichage est modifié selon ces conditions (hors cas particuliers) ? L'espacement entre les lignes (line-height) est augmenté jusqu'à 1,5 fois la taille de la police ; L'espacement suivant les paragraphes (balise <p>) est augmenté jusqu'à 2 fois la taille de la police ; L'espacement des lettres (letter-spacing) est augmenté jusqu'à 0,12 fois la taille de la police ; L'espacement des mots (word-spacing) est augmenté jusqu'à 0,16 fois la taille de la police.

Démo volontairement fautive

Ce texte tient sur plusieurs lignes : si l'interligne est augmenté de 1,5 fois, le contenu est rogné par la hauteur fixe.
Voir le code source du piège
<div style="height:30px;overflow:hidden;">Ce texte tient sur plusieurs lignes : si l'interligne est augmenté de 1,5 fois, le contenu est rogné par la hauteur fixe.</div>

Ce qui ne va pas : La hauteur fixe (30 px) associée à overflow:hidden coupe le texte dès que l'utilisateur augmente l'interligne, l'espacement des lettres ou des mots : le contenu devient illisible alors que ces réglages doivent être possibles sans perte.

Comment corriger : Ne pas fixer la hauteur des blocs de texte ni masquer le débordement : laisser les conteneurs s'adapter aux espacements redéfinis par l'utilisateur.

WCAG :
  • 1.4.12 Text Spacing (AA)

10.13 — Dans chaque page web, les contenus additionnels apparaissant à la prise de focus ou au survol d'un composant d'interface sont-ils contrôlables par l'utilisateur (hors cas particuliers) ?

10.13.1 manuel

Chaque contenu additionnel devenant visible à la prise de focus ou au survol d'un composant d'interface peut-il être masqué par une action de l'utilisateur sans déplacer le focus ou le pointeur de la souris (hors cas particuliers) ?

Démo volontairement fautive

Survolez ou tabulez sur ce lien : le contenu additionnel ne peut être masqué qu'en déplaçant le pointeur ou le focus.

Voir le code source du piège
<style>.f-10-13-1-tip{display:none}.f-10-13-1-trg:hover .f-10-13-1-tip,.f-10-13-1-trg:focus-within .f-10-13-1-tip{display:inline}</style><p class="f-10-13-1-trg">Survolez ou tabulez sur <a href="#">ce lien</a><span class="f-10-13-1-tip"> : le contenu additionnel ne peut être masqué qu'en déplaçant le pointeur ou le focus.</span></p>

Ce qui ne va pas : Le contenu additionnel (infobulle) apparaît au survol et au focus mais ne peut être masqué que si l'utilisateur déplace le pointeur ou le focus : aucune action (touche Échap, clic) ne permet de le masquer autrement, ce qui gêne la lecture du contenu situé dessous.

Comment corriger : Permettre de masquer le contenu additionnel sans déplacer pointeur ou focus, par exemple avec la touche Échap gérée par script, en plus de la fermeture au survol/focus perdu.

WCAG :
  • 1.4.13 Content on Hover or Focus (AA)

10.13.2 manuel

Chaque contenu additionnel qui apparait au survol d'un composant d'interface peut-il être survolé par le pointeur de la souris sans disparaître (hors cas particuliers) ?

Démo volontairement fautive

Survolez ce terme : l'infobulle est séparée du déclencheur par 40 px.

Voir le code source du piège
<style>.f-10-13-2-tip{display:none;margin-left:40px}.f-10-13-2-trg:hover+.f-10-13-2-tip{display:inline}</style><p><span class="f-10-13-2-trg">Survolez ce terme</span><span class="f-10-13-2-tip"> : l'infobulle est séparée du déclencheur par 40 px.</span></p>

Ce qui ne va pas : L'infobulle est affichée à 40 px du déclencheur : en déplaçant la souris vers elle, le pointeur quitte le déclencheur et l'infobulle disparaît avant d'avoir pu être survolée. Le contenu additionnel doit pouvoir être survolé par le pointeur sans disparaître.

Comment corriger : Supprimer l'espace entre le déclencheur et le contenu additionnel, ou le combler avec une zone « pont » qui maintient l'affichage pendant le déplacement du pointeur.

WCAG :
  • 1.4.13 Content on Hover or Focus (AA)

10.13.3 manuel

Chaque contenu additionnel qui apparaît à la prise de focus ou au survol d'un composant d'interface vérifie-t-il une de ces conditions (hors cas particuliers) ? Le contenu additionnel reste visible jusqu'à ce que l'utilisateur retire le pointeur souris ou le focus du contenu additionnel et du composant d'interface ayant déclenché son apparition ; Le contenu additionnel reste visible jusqu'à ce que l'utilisateur déclenche une action masquant ce contenu sans déplacer le focus ou le pointeur de la souris du composant d'interface ayant déclenché son apparition ; Le contenu additionnel reste visible jusqu'à ce qu'il ne soit plus valide.

Démo volontairement fautive

Survolez ou tabulez sur ce lien : dans l'implémentation réelle, une minuterie masque cette infobulle après 2 secondes.

Voir le code source du piège
<style>.f-10-13-3-tip{display:none}.f-10-13-3-trg:hover .f-10-13-3-tip,.f-10-13-3-trg:focus-within .f-10-13-3-tip{display:inline}</style><p class="f-10-13-3-trg">Survolez ou tabulez sur <a href="#">ce lien</a><span class="f-10-13-3-tip"> : dans l'implémentation réelle, une minuterie masque cette infobulle après 2 secondes.</span></p>

Ce qui ne va pas : Dans l'implémentation réelle, une minuterie masque l'infobulle après 2 secondes alors que l'utilisateur n'a ni retiré le pointeur, ni déplacé le focus, ni déclenché d'action : le contenu additionnel ne reste pas visible le temps nécessaire à sa lecture.

Comment corriger : Maintenir le contenu additionnel visible tant que le pointeur ou le focus est sur le déclencheur ou sur le contenu lui-même, ou jusqu'à une action explicite de masquage ou la perte de validité du contenu.

WCAG :
  • 1.4.13 Content on Hover or Focus (AA)

10.14 — Dans chaque page web, les contenus additionnels apparaissant via les styles CSS uniquement peuvent-ils être rendus visibles au clavier et par tout dispositif de pointage ?

10.14.1 manuel

Dans chaque page web, les contenus additionnels apparaissant au survol d'un composant d'interface via les styles CSS respectent-ils si nécessaire une de ces conditions ? Les contenus additionnels apparaissent également à l'activation du composant via le clavier et tout dispositif de pointage ; Les contenus additionnels apparaissent également à la prise de focus du composant ; Les contenus additionnels apparaissent également par le biais de l'activation ou de la prise de focus d'un autre composant.

Démo volontairement fautive

Survolez ce lien : contenu additionnel visible uniquement au survol de la souris.

Voir le code source du piège
<style>.f-10-14-1-tip{display:none}.f-10-14-1-trg:hover .f-10-14-1-tip{display:inline}</style><p class="f-10-14-1-trg">Survolez <a href="#">ce lien</a><span class="f-10-14-1-tip"> : contenu additionnel visible uniquement au survol de la souris.</span></p>

Ce qui ne va pas : Le contenu additionnel n'apparaît qu'au survol de la souris (CSS :hover) : un utilisateur clavier qui tabule jusqu'au lien ne le voit jamais, l'information lui est inaccessible.

Comment corriger : Déclencher l'affichage aussi à la prise de focus ou à l'activation : ajouter :focus, :focus-within ou un gestionnaire d'événement clavier sur le composant.

WCAG :
  • 2.1.1 Keyboard (A)

10.14.2 manuel

Dans chaque page web, les contenus additionnels apparaissant au focus d'un composant d'interface via les styles CSS respectent-ils si nécessaire une de ces conditions ? Les contenus additionnels apparaissent également à l'activation du composant via le clavier et tout dispositif de pointage ; Les contenus additionnels apparaissent également au survol du composant ; Les contenus additionnels apparaissent également par le biais de l'activation ou du survol d'un autre composant.

Démo volontairement fautive

Tabulez sur ce lien : contenu additionnel visible uniquement à la prise de focus.

Voir le code source du piège
<style>.f-10-14-2-tip{display:none}.f-10-14-2-trg:focus-within .f-10-14-2-tip{display:inline}</style><p class="f-10-14-2-trg">Tabulez sur <a href="#">ce lien</a><span class="f-10-14-2-tip"> : contenu additionnel visible uniquement à la prise de focus.</span></p>

Ce qui ne va pas : Le contenu additionnel n'apparaît qu'à la prise de focus (CSS :focus-within) : un utilisateur de souris qui survole le lien sans le focaliser ne voit jamais ce contenu.

Comment corriger : Déclencher l'affichage aussi au survol : ajouter :hover à la règle CSS, ou un gestionnaire d'événement de pointage, pour couvrir souris et clavier.

WCAG :
  • 2.1.1 Keyboard (A)

11. Formulaires (34 tests)

Formulaires : étiquettes, regroupements, aide à la saisie, gestion des erreurs, validation.

11.1 — Chaque champ de formulaire a-t-il une étiquette ?

11.1.1 collecteur · missing-form-label

Chaque champ de formulaire vérifie-t-il une de ces conditions ? Le champ de formulaire possède un attribut WAI-ARIA aria-labelledby référençant un passage de texte identifié ; Le champ de formulaire possède un attribut WAI-ARIA aria-label ; Une balise <label> ayant un attribut for est associée au champ de formulaire ; Le champ de formulaire possède un attribut title ; Un bouton adjacent au champ de formulaire lui fournit une étiquette visible et un élément <label> visuellement caché ou un attribut WAI-ARIA aria-label, aria-labelledby ou title lui fournit un nom accessible.

Démo volontairement fautive

Voir le code source du piège
<p><input type='text' placeholder='Nom'></p>

Ce qui ne va pas : Le champ n'est associé à aucune étiquette (<label>, aria-label ou aria-labelledby). Le placeholder ne remplace pas une étiquette : il disparaît à la saisie et n'est pas fiable pour les technologies d'assistance.

Comment corriger : Associer une étiquette : <label for="f-11-1-1-nom">Nom</label> <input type="text" id="f-11-1-1-nom">, ou aria-label="Nom" si l'étiquette visible est impossible.

WCAG :
  • 1.3.1 Info and Relationships (A)
  • 2.4.6 Headings and Labels (AA)
  • 3.3.2 Labels or Instructions (A)
  • 4.1.2 Name, Role, Value (A)

11.1.2 axe · label

Chaque champ de formulaire associé à une balise <label> ayant un attribut for, vérifie-t-il ces conditions ? Le champ de formulaire possède un attribut id ; La valeur de l'attribut for est égale à la valeur de l'attribut id du champ de formulaire associé.

Démo volontairement fautive

Voir le code source du piège
<label for='f-11-1-2-nom'>Nom</label> <input type='text'>

Ce qui ne va pas : La balise <label> possède un attribut for mais le champ n'a pas d'attribut id : la valeur f-11-1-2-nom ne référence aucun élément. L'association est rompue et le champ reste sans nom accessible.

Comment corriger : Donner au champ un id égal à la valeur du for : <label for="f-11-1-2-nom">Nom</label> <input type="text" id="f-11-1-2-nom">. Vérifier systématiquement la correspondance entre for et id.

WCAG :
  • 1.3.1 Info and Relationships (A)
  • 2.4.6 Headings and Labels (AA)
  • 3.3.2 Labels or Instructions (A)
  • 4.1.2 Name, Role, Value (A)

11.1.3 manuel

Chaque champ de formulaire ayant une étiquette dont le contenu n'est pas visible ou à proximité (masqué, aria-label) ou qui n’est pas accolé au champ (aria-labelledby), vérifie-t-il une de ses conditions ? Le champ de formulaire possède un attribut title dont le contenu permet de comprendre la nature de la saisie attendue ; Le champ de formulaire est accompagné d'un passage de texte accolé au champ qui devient visible à la prise de focus permettant de comprendre la nature de la saisie attendue ; Le champ de formulaire est accompagné d'un passage de texte visible accolé au champ permettant de comprendre la nature de la saisie attendue.

Démo volontairement fautive

Voir le code source du piège
<label for='f-11-1-3-nom' style='display:none'>Nom</label> <input type='text' id='f-11-1-3-nom'>

Ce qui ne va pas : L'étiquette est masquée (display:none) et aucune autre information (attribut title ou passage de texte accolé visible) n'indique la nature de la saisie attendue. L'utilisateur voyant ne sait pas quoi saisir dans ce champ.

Comment corriger : Rendre l'étiquette visible et accolée au champ, ou à défaut ajouter un attribut title="Nom" explicite ou un passage de texte accolé qui devient visible à la prise de focus.

WCAG :
  • 1.3.1 Info and Relationships (A)
  • 2.4.6 Headings and Labels (AA)
  • 3.3.2 Labels or Instructions (A)
  • 4.1.2 Name, Role, Value (A)

11.2 — Chaque étiquette associée à un champ de formulaire est-elle pertinente (hors cas particuliers) ?

11.2.1 manuel

Chaque balise <label> permet-elle de connaître la fonction exacte du champ de formulaire auquel elle est associée ?

Démo volontairement fautive

Voir le code source du piège
<label for='f-11-2-1-x'>Saisie</label> <input type='text' id='f-11-2-1-x'>

Ce qui ne va pas : L'étiquette « Saisie » est trop générique : elle ne permet pas de connaître la fonction exacte du champ (nom, e-mail, téléphone…). Une étiquette doit décrire précisément la donnée attendue.

Comment corriger : Remplacer par une étiquette explicite, par exemple <label for="f-11-2-1-x">Adresse e-mail</label>, et adapter le type du champ en conséquence.

WCAG :
  • 2.4.6 Headings and Labels (AA)
  • 2.5.3 Label in Name (A)
  • 3.3.2 Labels or Instructions (A)

11.2.2 manuel

Chaque attribut title permet-il de connaître la fonction exacte du champ de formulaire auquel il est associé ?

Démo volontairement fautive

Voir le code source du piège
<input type='text' title='Champ'>

Ce qui ne va pas : L'attribut title sert ici d'étiquette mais son contenu (« Champ ») ne permet pas de comprendre la nature de la saisie attendue. Le titre doit être une véritable étiquette descriptive.

Comment corriger : Utiliser un title explicite : <input type="text" title="Numéro de téléphone">, ou mieux, une <label> visible accolée au champ.

WCAG :
  • 2.4.6 Headings and Labels (AA)
  • 2.5.3 Label in Name (A)
  • 3.3.2 Labels or Instructions (A)

11.2.3 manuel

Chaque étiquette implémentée via l'attribut WAI-ARIA aria-label permet-elle de connaître la fonction exacte du champ de formulaire auquel elle est associée ?

Démo volontairement fautive

Voir le code source du piège
<input type='text' aria-label='Boîte de saisie'>

Ce qui ne va pas : L'étiquette fournie par aria-label (« Boîte de saisie ») est générique : elle ne permet pas de connaître la fonction exacte du champ. Un nom accessible doit être précis.

Comment corriger : Remplacer par un aria-label descriptif, par exemple aria-label="Numéro de commande", ou associer une <label> visible au champ.

WCAG :
  • 2.4.6 Headings and Labels (AA)
  • 2.5.3 Label in Name (A)
  • 3.3.2 Labels or Instructions (A)

11.2.4 manuel

Chaque passage de texte associé via l'attribut WAI-ARIA aria-labelledby permet-il de connaître la fonction exacte du champ de formulaire auquel il est associé ?

Démo volontairement fautive

Texte

Voir le code source du piège
<p id='f-11-2-4-a'>Texte</p> <input type='text' aria-labelledby='f-11-2-4-a'>

Ce qui ne va pas : Le passage de texte référencé par aria-labelledby (« Texte ») n'explique pas la fonction du champ. Le passage de texte doit décrire précisément la saisie attendue.

Comment corriger : Remplacer le contenu du passage par une étiquette explicite : <p id="f-11-2-4-a">Adresse de livraison</p>.

WCAG :
  • 2.4.6 Headings and Labels (AA)
  • 2.5.3 Label in Name (A)
  • 3.3.2 Labels or Instructions (A)

11.2.5 manuel

Chaque champ de formulaire ayant un intitulé visible vérifie-t-il ces conditions (hors cas particuliers) ? S'il est présent, le contenu de l'attribut WAI-ARIA aria-label du champ de formulaire contient au moins l'intitulé visible ; S'il est présent, le passage de texte lié au champ de formulaire via un attribut WAI-ARIA aria-labelledby contient au moins l'intitulé visible ; S'il est présent, le contenu de l'attribut title du champ de formulaire contient au moins l'intitulé visible ; S'il est présent le contenu de la balise <label> associé au champ de formulaire contient au moins l'intitulé visible.

Démo volontairement fautive

Voir le code source du piège
<label for='f-11-2-5-tel'>Téléphone</label> <input type='tel' id='f-11-2-5-tel' aria-label='Numéro'>

Ce qui ne va pas : L'intitulé visible de l'étiquette est « Téléphone » mais le nom accessible (via aria-label) est « Numéro » : l'intitulé visible n'est pas contenu dans le nom accessible. Les utilisateurs de synthèse vocale ne retrouvent pas le libellé affiché.

Comment corriger : Faire contenir au nom accessible l'intitulé visible, par exemple aria-label="Numéro de téléphone", qui contient bien « Téléphone ».

WCAG :
  • 2.4.6 Headings and Labels (AA)
  • 2.5.3 Label in Name (A)
  • 3.3.2 Labels or Instructions (A)

11.2.6 manuel

Chaque bouton adjacent au champ de formulaire qui fournit une étiquette visible permet-il de connaître la fonction exacte du champ de formulaire auquel il est associé ?

Démo volontairement fautive

Voir le code source du piège
<input type='text'> <button type='submit'>OK</button>

Ce qui ne va pas : C'est le bouton adjacent « OK » qui fournit l'étiquette visible du champ, mais cet intitulé ne permet pas de comprendre ce qu'il faut saisir. Le libellé du bouton doit décrire la fonction du champ.

Comment corriger : Rendre le libellé explicite : <button type="submit">Rechercher</button>, et associer idéalement une <label> au champ.

WCAG :
  • 2.4.6 Headings and Labels (AA)
  • 2.5.3 Label in Name (A)
  • 3.3.2 Labels or Instructions (A)

11.3 — Dans chaque formulaire, chaque étiquette associée à un champ de formulaire ayant la même fonction et répétée plusieurs fois dans une même page ou dans un ensemble de pages est-elle cohérente ?

11.3.1 manuel

Chaque étiquette associée à un champ de formulaire ayant la même fonction et répétée plusieurs fois dans une même page est-elle cohérente ?

Démo volontairement fautive

Voir le code source du piège
<label for='f-11-3-1-a'>Nom</label> <input type='text' id='f-11-3-1-a'> <label for='f-11-3-1-b'>Votre nom</label> <input type='text' id='f-11-3-1-b'>

Ce qui ne va pas : Deux champs ayant la même fonction (saisir son nom) portent des étiquettes différentes (« Nom » et « Votre nom ») dans la même page. Cette incohérence désoriente les utilisateurs, notamment ceux qui naviguent par la liste des champs.

Comment corriger : Utiliser une étiquette identique pour les champs de même fonction : « Nom » dans les deux cas.

WCAG :
  • 3.2.4 Consistent Identification (AA)

11.3.2 n/a

Chaque étiquette associée à un champ de formulaire ayant la même fonction et répétée dans un ensemble de pages est-elle cohérente ?

Démo volontairement fautive

Non démontrable en page statique — voir l'explication ci-dessous.

Ce qui ne va pas : Le test porte sur la cohérence des étiquettes entre les pages d'un même ensemble de pages (par exemple le champ de recherche dans l'en-tête de chaque page). Une seule page statique ne permet pas de comparer les étiquettes entre pages.

Comment corriger : En conditions réelles : vérifier que les champs de même fonction portent la même étiquette dans tout l'ensemble de pages (critère WCAG 3.2.4 « Identification cohérente »).

WCAG :
  • 3.2.4 Consistent Identification (AA)

11.4 — Dans chaque formulaire, chaque étiquette de champ et son champ associé sont-ils accolés (hors cas particuliers) ?

11.4.1 manuel

Chaque étiquette de champ et son champ associé sont-ils accolés ?

Démo volontairement fautive

Voir le code source du piège
<label for='f-11-4-1-adr'>Adresse</label> <input type='text' id='f-11-4-1-adr' style='margin-left:500px'>

Ce qui ne va pas : L'étiquette « Adresse » et son champ sont visuellement très éloignés l'un de l'autre : ils ne sont pas accolés. Sur mobile ou en zoom, l'utilisateur ne peut pas savoir quel champ correspond à quelle étiquette.

Comment corriger : Placer l'étiquette immédiatement à côté du champ (au-dessus ou à gauche) et supprimer l'espacement excessif. L'étiquette et son champ doivent être visuellement indiscociables.

WCAG :
  • 3.3.2 Labels or Instructions (A)

11.4.2 manuel

Chaque étiquette accolée à un champ (à l'exception des cases à cocher, bouton radio ou balises ayant un attribut WAI-ARIA role="checkbox", role="radio" ou role="switch"), vérifie-t-elle ces conditions (hors cas particuliers) ? L'étiquette est visuellement accolée immédiatement au-dessus ou à gauche du champ de formulaire lorsque le sens de lecture de la langue de l'étiquette est de gauche à droite ; L'étiquette est visuellement accolée immédiatement au-dessus ou à droite du champ de formulaire lorsque le sens de lecture de la langue de l'étiquette est de droite à gauche.

Démo volontairement fautive

Voir le code source du piège
<span style='display:inline-block'><input type='text' id='f-11-4-2-nom'> <label for='f-11-4-2-nom'>Nom</label></span>

Ce qui ne va pas : Pour un champ de saisie en lecture de gauche à droite, l'étiquette doit être immédiatement au-dessus ou à gauche du champ. Ici elle est placée à droite, ce qui casse le lien visuel entre l'étiquette et le champ.

Comment corriger : Placer l'étiquette avant le champ dans l'ordre visuel : <label for="f-11-4-2-nom">Nom</label> <input type="text" id="f-11-4-2-nom">.

WCAG :
  • 3.3.2 Labels or Instructions (A)

11.4.3 manuel

Chaque étiquette accolée à un champ de type checkbox ou radio ou à une balise ayant un attribut WAI-ARIA role="checkbox", role="radio" ou role="switch", vérifie-t-elle ces conditions (hors cas particuliers) ? L'étiquette est visuellement accolée immédiatement au-dessous ou à droite du champ de formulaire lorsque le sens de lecture de la langue de l'étiquette est de gauche à droite ; L'étiquette est visuellement accolée immédiatement au-dessous ou à gauche du champ de formulaire lorsque le sens de lecture de la langue de l'étiquette est de droite à gauche.

Démo volontairement fautive

Voir le code source du piège
<label for='f-11-4-3-ok'>J'accepte les conditions</label> <input type='checkbox' id='f-11-4-3-ok'>

Ce qui ne va pas : Pour une case à cocher ou un bouton radio, l'étiquette doit être immédiatement au-dessous ou à droite du champ. Ici elle est placée à gauche, ce qui ne respecte pas la position attendue.

Comment corriger : Placer l'étiquette après la case : <input type="checkbox" id="f-11-4-3-ok"> <label for="f-11-4-3-ok">J'accepte les conditions</label>.

WCAG :
  • 3.3.2 Labels or Instructions (A)

11.5 — Dans chaque formulaire, les champs de même nature sont-ils regroupés, si nécessaire ?

11.5.1 manuel

Les champs de même nature vérifient-ils l'une de ces conditions, si nécessaire ? Les champs de même nature sont regroupés dans une balise <fieldset> ; Les champs de même nature sont regroupés dans une balise possédant un attribut WAI-ARIA role="group" ; Les champs de même nature de type radio (<input type="radio">) ou balises possédant un attribut WAI-ARIA role="radio") sont regroupés dans une balise possédant un attribut WAI-ARIA role="radiogroup" ou role="group".

Démo volontairement fautive

Voir le code source du piège
<input type='radio' name='civ' id='f-11-5-1-m'> <label for='f-11-5-1-m'>M.</label> <input type='radio' name='civ' id='f-11-5-1-mme'> <label for='f-11-5-1-mme'>Mme</label>

Ce qui ne va pas : Les deux boutons radio « M. » / « Mme » sont de même nature mais ne sont pas regroupés dans un <fieldset> (ou un élément role="radiogroup"). La relation entre les options n'est pas restituée aux technologies d'assistance.

Comment corriger : Regrouper les options de même nature : <fieldset><legend>Civilité</legend> … </fieldset>.

WCAG :
  • 1.3.1 Info and Relationships (A)
  • 3.3.2 Labels or Instructions (A)

11.6 — Dans chaque formulaire, chaque regroupement de champs de même nature a-t-il une légende ?

11.6.1 manuel

Chaque regroupement de champs de même nature possède-t-il une légende ?

Démo volontairement fautive

Voir le code source du piège
<fieldset><input type='radio' name='civ' id='f-11-6-1-m'> <label for='f-11-6-1-m'>M.</label> <input type='radio' name='civ' id='f-11-6-1-mme'> <label for='f-11-6-1-mme'>Mme</label></fieldset>

Ce qui ne va pas : Le regroupement des champs existe (<fieldset>) mais aucune <legend> ne le décrit. Sans légende, les technologies d'assistance ne peuvent pas annoncer le thème du groupe.

Comment corriger : Ajouter une légende descriptive : <fieldset><legend>Civilité</legend> … </fieldset>.

WCAG :
  • 1.3.1 Info and Relationships (A)
  • 3.3.2 Labels or Instructions (A)

11.7 — Dans chaque formulaire, chaque légende associée à un regroupement de champs de même nature est-elle pertinente ?

11.7.1 manuel

Chaque légende associée à un regroupement de champs de même nature est-elle pertinente ?

Démo volontairement fautive

Formulaire
Voir le code source du piège
<fieldset><legend>Formulaire</legend><input type='radio' name='civ' id='f-11-7-1-m'> <label for='f-11-7-1-m'>M.</label> <input type='radio' name='civ' id='f-11-7-1-mme'> <label for='f-11-7-1-mme'>Mme</label></fieldset>

Ce qui ne va pas : La légende « Formulaire » est trop générale : elle ne décrit pas la nature des champs regroupés. Une légende doit résumer le thème du groupe, ici la civilité.

Comment corriger : Remplacer par une légende pertinente : <legend>Civilité</legend>.

WCAG :
  • 1.3.1 Info and Relationships (A)
  • 3.3.2 Labels or Instructions (A)

11.8 — Dans chaque formulaire, les items de même nature d'une liste de choix sont-ils regroupés de manière pertinente ?

11.8.1 manuel

Pour chaque balise <select>, les items de même nature d'une liste de choix sont-ils regroupés avec une balise <optgroup>, si nécessaire ?

Démo volontairement fautive

Voir le code source du piège
<label for='f-11-8-1-pays'>Pays</label> <select id='f-11-8-1-pays'><option>France</option><option>Allemagne</option><option>Canada</option><option>Belgique</option><option>Suisse</option></select>

Ce qui ne va pas : Les pays de la liste ne sont pas regroupés par zone géographique alors que le regroupement est pertinent (pays d'Europe, d'Amérique…). Une longue liste plate est difficile à parcourir, notamment au clavier.

Comment corriger : Regrouper les options de même nature avec <optgroup label="Europe"> et <optgroup label="Amérique">.

WCAG :
  • 1.3.1 Info and Relationships (A)

11.8.2 manuel

Dans chaque balise <select>, chaque balise <optgroup> possède-t-elle un attribut label ?

Démo volontairement fautive

Voir le code source du piège
<label for='f-11-8-2-p'>Pays</label> <select id='f-11-8-2-p'><optgroup><option>France</option><option>Allemagne</option></optgroup></select>

Ce qui ne va pas : Le regroupement <optgroup> existe mais l'attribut label, qui nomme le groupe, est absent. Les technologies d'assistance ne peuvent pas annoncer le nom du groupe.

Comment corriger : Ajouter l'attribut obligatoire : <optgroup label="Europe">.

WCAG :
  • 1.3.1 Info and Relationships (A)

11.8.3 manuel

Pour chaque balise <optgroup> ayant un attribut label, le contenu de l'attribut label est-il pertinent ?

Démo volontairement fautive

Voir le code source du piège
<label for='f-11-8-3-p'>Pays</label> <select id='f-11-8-3-p'><optgroup label='Divers'><option>France</option><option>Canada</option></optgroup></select>

Ce qui ne va pas : L'attribut label de l'optgroup (« Divers ») ne décrit pas correctement le contenu du groupe : la France et le Canada n'ont rien de commun. Le libellé doit refléter la nature commune des options.

Comment corriger : Utiliser un libellé pertinent, par exemple <optgroup label="Europe"> pour des pays européens.

WCAG :
  • 1.3.1 Info and Relationships (A)

11.9 — Dans chaque formulaire, l'intitulé de chaque bouton est-il pertinent (hors cas particuliers) ?

11.9.1 axe · button-name

L'intitulé de chaque bouton est-il pertinent ? S'il est présent, le contenu de l'attribut WAI-ARIA aria-label est pertinent ; S'il est présent, le passage de texte lié au bouton via un attribut WAI-ARIA aria-labelledby est pertinent ; S'il est présent, le contenu de l'attribut value d'une balise <input> de type submit, reset ou button est pertinent ; S'il est présent, le contenu de la balise <button> est pertinent ; S'il est présent, le contenu de l'attribut alt d'une balise <input> de type image est pertinent ; S'il est présent, le contenu de l'attribut title est pertinent.

Démo volontairement fautive

Voir le code source du piège
<button type='submit'></button>

Ce qui ne va pas : Le bouton ne contient aucun intitulé (texte, aria-label, aria-labelledby ou title). Un bouton sans nom accessible est annoncé de façon incompréhensible, voire ignoré par les technologies d'assistance : c'est le pire cas de non-pertinence de l'intitulé.

Comment corriger : Donner un intitulé pertinent : <button type="submit">Envoyer</button>. L'intitulé doit décrire l'action déclenchée, pas seulement sa position ou sa forme.

WCAG :
  • 2.5.3 Label in Name (A)
  • 4.1.2 Name, Role, Value (A)

11.9.2 manuel

Chaque bouton affichant un intitulé visible vérifie-t-il ces conditions (hors cas particuliers) ? S'il est présent, le contenu de l'attribut WAI-ARIA aria-label contient au moins l'intitulé visible ; S'il est présent, le passage de texte lié au bouton via un attribut WAI-ARIA aria-labelledby contient au moins l'intitulé visible ; S'il est présent, le contenu de l'attribut value d'une balise <input> de type submit, reset ou button contient au moins l'intitulé visible ; S'il est présent, le contenu de la balise <button> contient au moins l'intitulé visible ; S'il est présent, le contenu de l'attribut alt d'une balise <input> de type image contient au moins l'intitulé visible ; S'il est présent, le contenu de l'attribut title contient au moins l'intitulé visible.

Démo volontairement fautive

Voir le code source du piège
<button type='submit' aria-label='Soumettre le formulaire'>OK</button>

Ce qui ne va pas : L'intitulé visible du bouton est « OK » mais son nom accessible (aria-label) est « Soumettre le formulaire » : l'intitulé visible n'est pas contenu dans le nom accessible. La règle axe label-content-name-mismatch est expérimentale et n'est pas exécutée par ally-agent : contrôle manuel.

Comment corriger : Faire contenir au nom accessible l'intitulé visible, par exemple aria-label="OK, soumettre le formulaire", ou aligner simplement l'intitulé visible sur le nom accessible.

WCAG :
  • 2.5.3 Label in Name (A)
  • 4.1.2 Name, Role, Value (A)

11.10 — Dans chaque formulaire, le contrôle de saisie est-il utilisé de manière pertinente (hors cas particuliers) ?

11.10.1 manuel

Les indications du caractère obligatoire de la saisie des champs vérifient-elles une de ces conditions (hors cas particuliers) ? Une indication de champ obligatoire est visible et permet d'identifier nommément le champ concerné préalablement à la validation du formulaire ; Le champ obligatoire dispose de l'attribut aria-required="true" ou required préalablement à la validation du formulaire.

Démo volontairement fautive

Les champs marqués d'un astérisque sont obligatoires.

Voir le code source du piège
<p>Les champs marqués d'un astérisque sont obligatoires.</p> <label for='f-11-10-1-mail'>E-mail</label> <input type='email' id='f-11-10-1-mail'>

Ce qui ne va pas : Le champ e-mail est obligatoire dans le formulaire, mais aucune indication visible ne l'identifie comme tel (pas d'astérisque) et il ne possède ni required ni aria-required="true". L'utilisateur ne peut pas savoir qu'il doit le remplir.

Comment corriger : Ajouter une indication visible dans l'étiquette (« E-mail * ») ou l'attribut required (avec aria-required="true" si nécessaire).

WCAG :
  • 3.3.1 Error Identification (A)
  • 3.3.2 Labels or Instructions (A)

11.10.2 manuel

Les champs obligatoires ayant l'attribut aria-required="true" ou required vérifient-ils une de ces conditions ? Une indication de champ obligatoire est visible et située dans l'étiquette associée au champ préalablement à la validation du formulaire ; Une indication de champ obligatoire est visible et située dans le passage de texte associé au champ préalablement à la validation du formulaire.

Démo volontairement fautive

Voir le code source du piège
<label for='f-11-10-2-nom'>Nom</label> <input type='text' id='f-11-10-2-nom' required>

Ce qui ne va pas : Le champ possède l'attribut required, mais aucune indication visible (« * », « (obligatoire) »…) ne figure dans l'étiquette ni dans un passage de texte associé. L'utilisateur voyant ignore qu'il est obligatoire.

Comment corriger : Ajouter l'indication dans l'étiquette : <label for="f-11-10-2-nom">Nom *</label>, ou dans un passage de texte lié par aria-describedby.

WCAG :
  • 3.3.1 Error Identification (A)
  • 3.3.2 Labels or Instructions (A)

11.10.3 manuel

Les messages d'erreur indiquant l'absence de saisie d'un champ obligatoire vérifient-ils une de ces conditions ? Le message d'erreur indiquant l'absence de saisie d'un champ obligatoire est visible et permet d'identifier nommément le champ concerné ; Le champ obligatoire dispose de l'attribut aria-invalid="true".

Démo volontairement fautive

Ce champ est obligatoire.

Voir le code source du piège
<p class='erreur'>Ce champ est obligatoire.</p> <label for='f-11-10-3-nom'>Nom</label> <input type='text' id='f-11-10-3-nom'>

Ce qui ne va pas : Le message d'erreur ne permet pas d'identifier nommément le champ concerné : il ne le cite pas et n'est lié à aucun champ (pas de aria-describedby). Avec plusieurs champs en erreur, l'utilisateur ne sait pas lequel corriger.

Comment corriger : Nommer le champ dans le message (« Le champ Nom est obligatoire ») et le lier au champ avec aria-describedby="f-11-10-3-err".

WCAG :
  • 3.3.1 Error Identification (A)
  • 3.3.2 Labels or Instructions (A)

11.10.4 manuel

Les champs obligatoires ayant l'attribut aria-invalid="true" vérifient-ils une de ces conditions ? Le message d'erreur indiquant le caractère invalide de la saisie est visible et situé dans l'étiquette associée au champ ; Le message d'erreur indiquant le caractère invalide de la saisie est visible et situé dans le passage de texte associé au champ.

Démo volontairement fautive

Voir le code source du piège
<label for='f-11-10-4-mail'>E-mail</label> <input type='email' id='f-11-10-4-mail' aria-invalid='true'>

Ce qui ne va pas : Le champ est marqué aria-invalid="true" mais aucun message d'erreur visible n'est situé dans l'étiquette ni dans un passage de texte associé au champ. L'utilisateur ne sait pas pourquoi la saisie est invalide.

Comment corriger : Afficher un message d'erreur visible dans l'étiquette ou lié par aria-describedby, par exemple « E-mail : saisie invalide ».

WCAG :
  • 3.3.1 Error Identification (A)
  • 3.3.2 Labels or Instructions (A)

11.10.5 manuel

Les instructions et indications du type de données et/ou de format obligatoires vérifient-elles une de ces conditions ? Une instruction ou une indication du type de données et/ou de format obligatoire est visible et permet d'identifier nommément le champ concerné préalablement à la validation du formulaire ; Une instruction ou une indication du type de données et/ou de format obligatoire est visible dans l'étiquette ou le passage de texte associé au champ préalablement à la validation du formulaire.

Démo volontairement fautive

Voir le code source du piège
<label for='f-11-10-5-ddn'>Date de naissance</label> <input type='text' id='f-11-10-5-ddn'>

Ce qui ne va pas : Le champ attend une date mais aucune instruction visible n'indique le format requis (JJ/MM/AAAA). L'utilisateur ne peut pas saisir une valeur valide du premier coup.

Comment corriger : Ajouter l'indication dans l'étiquette ou en passage de texte : « Date de naissance (format JJ/MM/AAAA) », ou utiliser <input type="date">.

WCAG :
  • 3.3.1 Error Identification (A)
  • 3.3.2 Labels or Instructions (A)

11.10.6 manuel

Les messages d'erreurs fournissant une instruction ou une indication du type de données et/ou de format obligatoire des champs vérifient-ils une de ces conditions ? Le message d'erreur fournissant une instruction ou une indication du type de données et/ou de format obligatoires est visible et identifie le champ concerné ; Le champ dispose de l'attribut aria-invalid="true".

Démo volontairement fautive

Format de date invalide.

Voir le code source du piège
<p class='erreur'>Format de date invalide.</p> <label for='f-11-10-6-ddn'>Date de naissance</label> <input type='text' id='f-11-10-6-ddn'>

Ce qui ne va pas : Le message d'erreur indique un format invalide mais n'identifie pas le champ concerné et n'est lié à aucun champ. L'utilisateur ne peut pas rattacher l'erreur au champ à corriger.

Comment corriger : Lier le message au champ (aria-describedby) et le rendre explicite : « Date de naissance : format attendu JJ/MM/AAAA ».

WCAG :
  • 3.3.1 Error Identification (A)
  • 3.3.2 Labels or Instructions (A)

11.10.7 manuel

Les champs ayant l'attribut aria-invalid="true" dont la saisie requiert un type de données et/ou de format obligatoires vérifient-ils une de ces conditions ? Une instruction ou une indication du type de données et/ou de format obligatoire est visible et située dans la balise <label> associée au champ ; Une instruction ou une indication du type de données et/ou de format obligatoire est visible et située dans le passage de texte associé au champ.

Démo volontairement fautive

Voir le code source du piège
<label for='f-11-10-7-cp'>Code postal</label> <input type='text' id='f-11-10-7-cp' aria-invalid='true'>

Ce qui ne va pas : Le champ est en erreur (aria-invalid="true") alors que la saisie requiert un format précis, mais aucune instruction de format n'est visible dans l'étiquette ni dans un passage de texte associé. L'utilisateur ne peut pas corriger sa saisie.

Comment corriger : Ajouter le format attendu dans l'étiquette (« Code postal (5 chiffres) ») ou dans un passage de texte lié par aria-describedby.

WCAG :
  • 3.3.1 Error Identification (A)
  • 3.3.2 Labels or Instructions (A)

11.11 — Dans chaque formulaire, le contrôle de saisie est-il accompagné, si nécessaire, de suggestions facilitant la correction des erreurs de saisie ?

11.11.1 manuel

Pour chaque erreur de saisie, les types et les formats de données sont-ils suggérés, si nécessaire ?

Démo volontairement fautive

Saisie incorrecte.

Voir le code source du piège
<p class='erreur'>Saisie incorrecte.</p> <label for='f-11-11-1-tel'>Téléphone</label> <input type='text' id='f-11-11-1-tel'>

Ce qui ne va pas : Le message d'erreur ne suggère ni le type ni le format de données attendus. Sans suggestion, l'utilisateur doit deviner la correction (chiffres, longueur, séparateurs…).

Comment corriger : Suggérer le type et le format attendus : « Le numéro doit contenir 10 chiffres, sans espaces ni points ».

WCAG :
  • 3.3.3 Error Suggestion (AA)

11.11.2 manuel

Pour chaque erreur de saisie, des exemples de valeurs attendues sont-ils suggérés, si nécessaire ?

Démo volontairement fautive

Numéro invalide.

Voir le code source du piège
<p class='erreur'>Numéro invalide.</p> <label for='f-11-11-2-tel'>Téléphone</label> <input type='text' id='f-11-11-2-tel'>

Ce qui ne va pas : Le message d'erreur n'illustre pas la valeur attendue. Un exemple concret aide l'utilisateur à comprendre et à corriger sa saisie, surtout pour les formats inhabituels.

Comment corriger : Ajouter un exemple de valeur attendue : « Exemple : 06 12 34 56 78 », idéalement en plus du type de données requis.

WCAG :
  • 3.3.3 Error Suggestion (AA)

11.12 — Pour chaque formulaire qui modifie ou supprime des données, ou qui transmet des réponses à un test ou à un examen, ou dont la validation a des conséquences financières ou juridiques, les données saisies peuvent-elles être modifiées, mises à jour ou récupérées par l'utilisateur ?

11.12.1 manuel

Pour chaque formulaire qui modifie ou supprime des données, ou qui transmet des réponses à un test ou un examen, ou dont la validation a des conséquences financières ou juridiques, la saisie des données vérifie-t-elle une de ces conditions ? L'utilisateur peut modifier ou annuler les données et les actions effectuées sur ces données après la validation du formulaire ; L'utilisateur peut vérifier et corriger les données avant la validation d'un formulaire en plusieurs étapes ; Un mécanisme de confirmation explicite, via une case à cocher (balise <input> de type checkbox ou balise ayant un attribut WAI-ARIA role="checkbox") ou une étape supplémentaire, est présent.

Démo volontairement fautive

Voir le code source du piège
<form action='supprimer.html'><button type='submit'>Supprimer mon compte</button></form>

Ce qui ne va pas : Ce formulaire supprime un compte (conséquence majeure sur des données) sans mécanisme de confirmation explicite : ni case à cocher, ni étape de vérification, ni possibilité d'annuler après validation. Une erreur de clic est irréversible.

Comment corriger : Ajouter une confirmation explicite (case à cocher « Je confirme la suppression » ou étape de récapitulation avec validation), et permettre de modifier les données avant l'envoi.

WCAG :
  • 3.3.4 Error Prevention (Legal, Financial, Data) (AA)

11.12.2 manuel

Chaque formulaire dont la validation modifie ou supprime des données à caractère financier, juridique ou personnel vérifie-t-il une de ces conditions ? Un mécanisme permet de récupérer les données supprimées ou modifiées par l'utilisateur ; Un mécanisme de demande de confirmation explicite de la suppression ou de la modification, via un champ de formulaire ou une étape supplémentaire, est proposé.

Démo volontairement fautive

Voir le code source du piège
<form action='effacer.html'><button type='submit'>Effacer mes données personnelles</button></form>

Ce qui ne va pas : Ce formulaire supprime des données à caractère personnel sans demande de confirmation explicite ni mécanisme de récupération. La suppression est déclenchée dès la validation, sans retour possible.

Comment corriger : Proposer une demande de confirmation explicite (étape supplémentaire ou champ de type checkbox) et, si possible, un mécanisme de récupération des données supprimées.

WCAG :
  • 3.3.4 Error Prevention (Legal, Financial, Data) (AA)

11.13 — La finalité d'un champ de saisie peut-elle être déduite pour faciliter le remplissage automatique des champs avec les données de l'utilisateur ?

11.13.1 axe · autocomplete-valid

Chaque champ de formulaire dont l'objet se rapporte à une information concernant l'utilisateur vérifie-t-il ces conditions ? Le champ de formulaire possède un attribut autocomplete ; L'attribut autocomplete est pourvu d'une valeur présente dans la liste des valeurs possibles pour l'attribut autocomplete associés à un champ de formulaire ; La valeur indiquée pour l'attribut autocomplete est pertinente au regard du type d'information attendu.

Démo volontairement fautive

Voir le code source du piège
<label for='f-11-13-1-cp'>Code postal</label> <input type='text' id='f-11-13-1-cp' autocomplete='postal'>

Ce qui ne va pas : Le champ porte un attribut autocomplete dont la valeur « postal » n'existe pas dans la liste officielle (il faut « postal-code ») : l'autocomplétion ne fonctionnera pas. Le cas le plus fréquent reste l'absence totale d'attribut, que seul un audit humain peut constater.

Comment corriger : Utiliser une valeur de la liste officielle et pertinente pour le champ : autocomplete="postal-code", ou autocomplete="email" pour un e-mail, autocomplete="tel" pour un téléphone…

WCAG :
  • 1.3.5 Identify Input Purpose (AA)

12. Navigation (19 tests)

Navigation : menus, plan du site, moteur de recherche, liens d'évitement, ordre de tabulation, raccourcis clavier.

12.1 — Chaque ensemble de pages dispose-t-il de deux systèmes de navigation différents, au moins (hors cas particuliers) ?

12.1.1 manuel

Chaque ensemble de pages vérifie-t-il une de ces conditions (hors cas particuliers) ? Un menu de navigation et un plan du site sont présents ; Un menu de navigation et un moteur de recherche sont présents ; Un moteur de recherche et un plan du site sont présents.

Démo volontairement fautive

Voir le code source du piège
<nav><a href='accueil.html'>Accueil</a> <a href='contact.html'>Contact</a></nav>

Ce qui ne va pas : La page ne propose qu'un menu de navigation : aucun lien vers un plan du site ni moteur de recherche n'est présent. Le test exige deux systèmes de navigation différents sur l'ensemble de pages, ce qui ne peut être confirmé qu'en parcourant le site.

Comment corriger : Ajouter au moins un second système de navigation : un lien vers une page « Plan du site » ou un moteur de recherche interne, accessible depuis toutes les pages.

WCAG :
  • 2.4.5 Multiple Ways (AA)

12.2 — Dans chaque ensemble de pages, le menu et les barres de navigation sont-ils toujours à la même place (hors cas particuliers) ?

12.2.1 n/a

Dans chaque ensemble de pages, chaque page disposant d'un menu ou de barres de navigation vérifie-t-elle ces conditions (hors cas particuliers) ? Le menu ou les barres de navigation sont toujours à la même place dans la présentation ; Le menu ou les barres de navigation se présentent toujours dans le même ordre relatif dans le code source.

Démo volontairement fautive

Non démontrable en page statique — voir l'explication ci-dessous.

Ce qui ne va pas : Le test vérifie que le menu et les barres de navigation sont toujours à la même place et dans le même ordre dans toutes les pages d'un ensemble. Une page statique unique ne permet pas de comparer la position et l'ordre du menu entre pages.

Comment corriger : En conditions réelles : maintenir la même position visuelle et le même ordre relatif du menu dans le code source de chaque page de l'ensemble (critère WCAG 3.2.3 « Navigation cohérente »).

WCAG :
  • 3.2.3 Consistent Navigation (AA)

12.3 — La page « plan du site » est-elle pertinente ?

12.3.1 manuel

La page « plan du site » est-elle représentative de l'architecture générale du site ?

Démo volontairement fautive

Plan du site

Voir le code source du piège
<h2>Plan du site</h2> <ul><li><a href='accueil.html'>Accueil</a></li></ul>

Ce qui ne va pas : La page « plan du site » ne liste qu'une seule page : elle n'est pas représentative de l'architecture générale du site. Un plan du site doit refléter l'ensemble des rubriques et sous-rubriques.

Comment corriger : Établir un plan exhaustif reprenant toutes les sections importantes du site, organisées hiérarchiquement (rubriques et sous-rubriques).

WCAG :
  • 2.4.5 Multiple Ways (AA)

12.3.2 manuel

Les liens du plan du site sont-ils fonctionnels ?

Démo volontairement fautive

Voir le code source du piège
<ul><li><a href='page-inexistante.html'>Actualités</a></li></ul>

Ce qui ne va pas : Le lien du plan du site pointe vers une page qui n'existe pas : le lien n'est pas fonctionnel. L'utilisateur aboutit sur une erreur 404.

Comment corriger : Vérifier que chaque lien du plan du site pointe vers une page existante et corriger les destinations cassées.

WCAG :
  • 2.4.5 Multiple Ways (AA)

12.3.3 manuel

Les liens du plan du site renvoient-ils bien vers les pages indiquées par l'intitulé ?

Démo volontairement fautive

Voir le code source du piège
<ul><li><a href='accueil.html'>Contact</a></li></ul>

Ce qui ne va pas : L'intitulé du lien (« Contact ») ne correspond pas à la page de destination (accueil.html). L'utilisateur est conduit vers une page autre que celle annoncée par l'intitulé.

Comment corriger : Faire pointer chaque intitulé vers la page correspondante : <a href="contact.html">Contact</a>.

WCAG :
  • 2.4.5 Multiple Ways (AA)

12.4 — Dans chaque ensemble de pages, la page « plan du site » est-elle atteignable de manière identique ?

12.4.1 n/a

Dans chaque ensemble de pages, la page « plan du site » est-elle accessible à partir d'une fonctionnalité identique ?

Démo volontairement fautive

Non démontrable en page statique — voir l'explication ci-dessous.

Ce qui ne va pas : Le test vérifie que la page « plan du site » est atteignable par une fonctionnalité identique depuis toutes les pages de l'ensemble. Une page statique unique ne permet pas de vérifier la présence et l'identité de cette fonctionnalité sur l'ensemble des pages.

Comment corriger : En conditions réelles : placer un lien « Plan du site » identique (même intitulé, même destination) dans toutes les pages de l'ensemble.

WCAG :
  • 2.4.5 Multiple Ways (AA)
  • 3.2.3 Consistent Navigation (AA)

12.4.2 n/a

Dans chaque ensemble de pages, la fonctionnalité vers la page « plan du site » est-elle située à la même place dans la présentation ?

Démo volontairement fautive

Non démontrable en page statique — voir l'explication ci-dessous.

Ce qui ne va pas : Le test vérifie que la fonctionnalité d'accès au plan du site est toujours située à la même place dans la présentation des pages de l'ensemble. Impossible à constater sur une seule page statique.

Comment corriger : En conditions réelles : positionner le lien « Plan du site » au même endroit visuel (par exemple en pied de page) sur toutes les pages.

WCAG :
  • 2.4.5 Multiple Ways (AA)
  • 3.2.3 Consistent Navigation (AA)

12.4.3 n/a

Dans chaque ensemble de pages, la fonctionnalité vers la page « plan du site » se présente-t-elle toujours dans le même ordre relatif dans le code source ?

Démo volontairement fautive

Non démontrable en page statique — voir l'explication ci-dessous.

Ce qui ne va pas : Le test vérifie que la fonctionnalité d'accès au plan du site apparaît toujours dans le même ordre relatif dans le code source des pages de l'ensemble. Une page isolée ne permet pas cette comparaison.

Comment corriger : En conditions réelles : maintenir le lien « Plan du site » au même endroit du DOM (même ordre relatif) dans chaque page.

WCAG :
  • 2.4.5 Multiple Ways (AA)
  • 3.2.3 Consistent Navigation (AA)

12.5 — Dans chaque ensemble de pages, le moteur de recherche est-il atteignable de manière identique ?

12.5.1 n/a

Dans chaque ensemble de pages, le moteur de recherche est-il accessible à partir d'une fonctionnalité identique ?

Démo volontairement fautive

Non démontrable en page statique — voir l'explication ci-dessous.

Ce qui ne va pas : Le test vérifie que le moteur de recherche est accessible par une fonctionnalité identique dans toutes les pages de l'ensemble. Une page statique unique ne permet pas de vérifier l'ensemble, et un vrai moteur de recherche nécessite par ailleurs un backend.

Comment corriger : En conditions réelles : proposer la même fonctionnalité de recherche (même champ, même intitulé) dans toutes les pages de l'ensemble.

WCAG :
  • 3.2.3 Consistent Navigation (AA)

12.5.2 n/a

Dans chaque ensemble de pages, la fonctionnalité vers le moteur de recherche est-elle située à la même place dans la présentation ?

Démo volontairement fautive

Non démontrable en page statique — voir l'explication ci-dessous.

Ce qui ne va pas : Le test vérifie que la fonctionnalité de recherche est située à la même place dans la présentation de chaque page de l'ensemble. Position et présentation inter-pages non vérifiables sur une page unique.

Comment corriger : En conditions réelles : placer le moteur de recherche au même endroit visuel sur toutes les pages (par exemple dans l'en-tête, à droite).

WCAG :
  • 3.2.3 Consistent Navigation (AA)

12.5.3 n/a

Dans chaque ensemble de pages, la fonctionnalité vers le moteur de recherche se présente-t-elle toujours dans le même ordre relatif dans le code source ?

Démo volontairement fautive

Non démontrable en page statique — voir l'explication ci-dessous.

Ce qui ne va pas : Le test vérifie que la fonctionnalité de recherche apparaît dans le même ordre relatif dans le code source de chaque page de l'ensemble. Comparaison impossible sur une page isolée.

Comment corriger : En conditions réelles : maintenir le moteur de recherche au même endroit du DOM dans toutes les pages de l'ensemble.

WCAG :
  • 3.2.3 Consistent Navigation (AA)

12.6 — Les zones de regroupement de contenus présentes dans plusieurs pages web (zones d'en-tête, de navigation principale, de contenu principal, de pied de page et de moteur de recherche) peuvent-elles être atteintes ou évitées ?

12.6.1 partiel

Dans chaque page web où elles sont présentes, la zone d'en-tête, de navigation principale, de contenu principal, de pied de page et de moteur de recherche respectent-elles au moins une de ces conditions : La zone possède un rôle WAI-ARIA de type landmark correspondant à sa nature ; La zone possède un titre dont le contenu permet de comprendre la nature du contenu de la zone ; La zone peut être masquée par le biais d'un bouton précédent directement la zone dans l'ordre du code source ; La zone peut être évitée par le biais d'un lien d'évitement précédent directement la zone dans l'ordre du code source ; La zone peut être atteinte par le biais d'un lien d'accès rapide visible ou, à défaut, visible à la prise de focus.

Démo volontairement fautive

Logo du site
Article principal
Mentions légales
Voir le code source du piège
<div class='entete'>Logo du site</div> <div class='contenu'>Article principal</div> <div class='pied'>Mentions légales</div>

Ce qui ne va pas : Les zones d'en-tête, de contenu principal et de pied de page sont des <div> sans rôle de landmark, sans titre et sans lien d'évitement : elles ne peuvent être ni identifiées ni évitées par les technologies d'assistance. Un utilisateur de lecteur d'écran doit traverser ces zones sans pouvoir les repérer ni les contourner.

Comment corriger : Utiliser les éléments de structure natifs <header>, <main>, <footer> (ou les rôles banner, main, contentinfo), ou ajouter des liens d'évitement avant chaque zone.

WCAG :
  • 1.3.1 Info and Relationships (A)
  • 2.4.1 Bypass Blocks (A)
  • 4.1.2 Name, Role, Value (A)

12.7 — Dans chaque page web, un lien d'évitement ou d'accès rapide à la zone de contenu principal est-il présent (hors cas particuliers) ?

12.7.1 manuel

Dans chaque page web, un lien permet-il d'éviter la zone de contenu principal ou d'y accéder (hors cas particuliers) ?

Démo volontairement fautive

Voir le code source du piège
<header><nav><a href='accueil.html'>Accueil</a> <a href='contact.html'>Contact</a></nav></header> <main><h1>Contenu</h1></main>

Ce qui ne va pas : Aucun lien d'évitement ou d'accès rapide ne permet d'atteindre directement la zone de contenu principal. Un utilisateur clavier doit parcourir tout le menu à chaque page avant d'atteindre le contenu.

Comment corriger : Ajouter en tout début de page un lien d'évitement : <a href="#f-12-7-1-contenu">Aller au contenu</a> pointant vers l'id du <main>. Ce lien doit être le premier élément focusable de la page.

WCAG :
  • 2.4.1 Bypass Blocks (A)
  • 2.4.3 Focus Order (A)
  • 3.2.3 Consistent Navigation (AA)

12.7.2 manuel

Dans chaque ensemble de pages, le lien d'évitement ou d'accès rapide à la zone de contenu principal vérifie-t-il ces conditions (hors cas particuliers) ? Le lien est situé à la même place dans la présentation ; Le lien se présente toujours dans le même ordre relatif dans le code source ; Le lien est visible ou, à défaut, visible à la prise de focus ; Le lien est fonctionnel.

Démo volontairement fautive

Voir le code source du piège
<a href='#f-12-7-2-contenu' style='display:none'>Aller au contenu</a> <main id='f-12-7-2-contenu'>Contenu</main>

Ce qui ne va pas : Le lien d'évitement existe mais il est définitivement masqué (display:none) : il n'est ni visible ni visible à la prise de focus, donc inutilisable pour les utilisateurs clavier. Un lien d'évitement doit devenir visible dès qu'il reçoit le focus.

Comment corriger : Masquer le lien uniquement tant qu'il n'a pas le focus (déplacement hors écran puis :focus visible), et vérifier qu'il déplace bien le focus vers le contenu.

WCAG :
  • 2.4.1 Bypass Blocks (A)
  • 2.4.3 Focus Order (A)
  • 3.2.3 Consistent Navigation (AA)

12.8 — Dans chaque page web, l'ordre de tabulation est-il cohérent ?

12.8.1 manuel

Dans chaque page web, l'ordre de tabulation dans le contenu est-il cohérent ?

Démo volontairement fautive

Voir le code source du piège
<a href='#'>Lien 1</a> <a href='#' tabindex='3'>Lien 3</a> <a href='#' tabindex='1'>Lien 2</a>

Ce qui ne va pas : Les tabindex positifs (1, 3) imposent un ordre de tabulation artificiel qui ne correspond pas à l'ordre visuel des liens. La navigation clavier devient illisible.

Comment corriger : Supprimer les tabindex positifs et laisser l'ordre naturel du DOM refléter l'ordre visuel. Un tabindex="0" suffit pour rendre un élément non interactif focusable.

WCAG :
  • 2.4.3 Focus Order (A)

12.8.2 n/a

Pour chaque script qui met à jour ou insère un contenu, l'ordre de tabulation reste-t-il cohérent ?

Démo volontairement fautive

Non démontrable en page statique — voir l'explication ci-dessous.

Ce qui ne va pas : Le test porte sur des scripts qui mettent à jour ou insèrent du contenu dynamiquement et sur le maintien de l'ordre de tabulation après ces mises à jour. Cela nécessite un JavaScript exécuté au moment du chargement, impossible dans une page statique sans script.

Comment corriger : En conditions réelles : après toute insertion ou mise à jour de contenu par script, vérifier que le focus et l'ordre de tabulation restent cohérents avec l'ordre visuel.

WCAG :
  • 2.4.3 Focus Order (A)

12.9 — Dans chaque page web, la navigation ne doit pas contenir de piège au clavier. Cette règle est-elle respectée ?

12.9.1 manuel

Dans chaque page web, chaque élément recevant le focus vérifie-t-il une de ces conditions ? Il est possible d'atteindre l'élément suivant ou précédent pouvant recevoir le focus avec la touche de tabulation ; L'utilisateur est informé d'un mécanisme fonctionnel permettant d'atteindre au clavier l'élément suivant ou précédent pouvant recevoir le focus.

Démo volontairement fautive

Voir le code source du piège
<input type='text' onblur='this.focus()' placeholder='Ne me quittez pas'>

Ce qui ne va pas : L'attribut onblur refocalise immédiatement le champ dès qu'il perd le focus : l'utilisateur clavier ne peut plus atteindre l'élément suivant ou précédent. C'est un piège au clavier.

Comment corriger : Supprimer ce comportement et laisser la tabulation naturelle quitter le champ ; si un garde-fou est nécessaire, prévoir un mécanisme de sortie explicite et documenté.

WCAG :
  • 2.1.1 Keyboard (A)
  • 2.1.2 No Keyboard Trap (A)

12.10 — Dans chaque page web, les raccourcis clavier n'utilisant qu'une seule touche (lettre minuscule ou majuscule, ponctuation, chiffre ou symbole) sont-ils contrôlables par l’utilisateur ?

12.10.1 manuel

Dans chaque page web, chaque raccourci clavier n'utilisant qu'une seule touche (lettre minuscule ou majuscule, ponctuation, chiffre ou symbole) vérifie-t-il l'une de ces conditions ? Un mécanisme est disponible pour désactiver le raccourci clavier ; Un mécanisme est disponible pour configurer la touche de raccourci clavier au moyen des touches de modification (Ctrl, Alt, Maj, etc) ; Dans le cas d'un composant d'interface utilisateur, le raccourci clavier qui lui est associé ne peut être activé que si le focus clavier est sur ce composant.

Démo volontairement fautive

Contenu de la page
Voir le code source du piège
<div onkeydown='if(event.keyCode==77) alert(1)'>Contenu de la page</div>

Ce qui ne va pas : Un raccourci clavier mono-touche (la touche « m », code 77) déclenche une action, sans mécanisme pour le désactiver ou le reconfigurer avec une touche de modification. Les utilisateurs de dictée ou malvoyants peuvent déclencher l'action par accident.

Comment corriger : Exiger une touche de modification (par exemple Ctrl+Alt+M), ou proposer un mécanisme de désactivation et de configuration du raccourci.

WCAG :
  • 2.1.4 Character Key Shortcuts (A)

12.11 — Dans chaque page web, les contenus additionnels apparaissant au survol, à la prise de focus ou à l'activation d'un composant d'interface sont-ils si nécessaire atteignables au clavier ?

12.11.1 manuel

Dans chaque page web, les contenus additionnels apparaissant au survol, à la prise de focus ou à l'activation d'un composant d'interface sont-ils si nécessaire atteignables au clavier ?

Démo volontairement fautive

Voir le code source du piège
<button type='button' aria-describedby='f-12-11-1-aide'>Aide</button> <p id='f-12-11-1-aide' style='display:none'>Aide détaillée de la page</p>

Ce qui ne va pas : Le contenu additionnel (le passage d'aide) n'apparaît qu'au survol ou à l'activation, mais il est définitivement masqué (display:none) : il n'est jamais atteignable au clavier, même quand le bouton a le focus. L'aide reste donc invisible pour les utilisateurs clavier.

Comment corriger : Afficher le passage d'aide lorsque le bouton reçoit le focus (et pas seulement au survol), et le laisser accessible au clavier tant qu'il est ouvert.

WCAG :
  • 2.1.1 Keyboard (A)

13. Consultation (21 tests)

Consultation : rafraîchissements, fenêtres, téléchargements, contenus cryptiques, flash, mouvement, gestes et interactions tactiles.

13.1 — Pour chaque page web, l'utilisateur a-t-il le contrôle de chaque limite de temps modifiant le contenu (hors cas particuliers) ?

13.1.1 axe · meta-refresh

Pour chaque page web, chaque procédé de rafraîchissement (balise <object>, balise <embed>, balise <svg>, balise <canvas>, balise <meta>) vérifie-t-il une de ces conditions (hors cas particuliers) ? L'utilisateur peut arrêter ou relancer le rafraîchissement ; L'utilisateur peut augmenter la limite de temps entre deux rafraîchissements de dix fois, au moins ; L'utilisateur est averti de l'imminence du rafraîchissement et dispose de vingt secondes, au moins, pour augmenter la limite de temps avant le prochain rafraîchissement ; La limite de temps entre deux rafraîchissements est de vingt heures, au moins.

Démo volontairement fautive

Voir le code source du piège
<meta http-equiv='refresh' content='3600'>

Ce qui ne va pas : Ce rafraîchissement automatique recharge la page sans action de l'utilisateur. Le délai est ici allongé (1 heure au lieu de quelques secondes en conditions réelles) pour ne pas interrompre la consultation de cette page benchmark : en production, un tel meta refresh fait perdre la position de lecture, le contenu saisi et peut déclencher un rechargement pendant une action.

Comment corriger : Supprimer le rafraîchissement automatique. Si un contenu doit être actualisé, proposer un bouton explicite, ou utiliser fetch/SSE avec un message de statut accessible (role="status").

WCAG :
  • 2.2.1 Timing adjustable (A)
  • 2.2.2 Pause, Stop, Hide (A)

13.1.2 axe · meta-refresh

Pour chaque page web, chaque procédé de redirection effectué via une balise <meta> est-il immédiat (hors cas particuliers) ?

Démo volontairement fautive

Voir le code source du piège
<meta http-equiv='refresh' content='3600; url=page2.html'>

Ce qui ne va pas : La redirection n'est pas immédiate : le navigateur attend le délai du meta refresh avant de partir vers page2.html. Un délai non nul est une violation du test (en conditions réelles, quelques secondes ; il est allongé ici pour ne pas interrompre la consultation de la page benchmark). L'utilisateur ne contrôle pas ce changement de page.

Comment corriger : Remplacer par une vraie redirection immédiate côté serveur (statut HTTP 301/302) ou par un lien que l'utilisateur active lui-même.

WCAG :
  • 2.2.1 Timing adjustable (A)
  • 2.2.2 Pause, Stop, Hide (A)

13.1.3 n/a

Pour chaque page web, chaque procédé de redirection effectué via un script vérifie-t-il une de ces conditions (hors cas particuliers) ? L'utilisateur peut arrêter ou relancer la redirection ; L'utilisateur peut augmenter la limite de temps avant la redirection de dix fois, au moins ; L'utilisateur est averti de l'imminence de la redirection et dispose de vingt secondes, au moins, pour augmenter la limite de temps avant la prochaine redirection ; La limite de temps avant la redirection est de vingt heures, au moins.

Démo volontairement fautive

Non démontrable en page statique — voir l'explication ci-dessous.

Ce qui ne va pas : Le test porte sur les redirections effectuées par script (par exemple setTimeout ou location.href en JavaScript). Un script exécutable n'est pas démontrable dans une page statique sans code JavaScript.

Comment corriger : En conditions réelles : ne pas utiliser de redirection par script différée ; sinon proposer un lien de redirection manuel et un contrôle de la limite de temps.

WCAG :
  • 2.2.1 Timing adjustable (A)
  • 2.2.2 Pause, Stop, Hide (A)

13.1.4 n/a

Pour chaque page web, chaque procédé limitant le temps d'une session vérifie-t-il une de ces conditions (hors cas particuliers) ? L'utilisateur peut supprimer la limite de temps ; L'utilisateur peut augmenter la limite de temps ; La limite de temps avant la fin de la session est de vingt heures au moins.

Démo volontairement fautive

Non démontrable en page statique — voir l'explication ci-dessous.

Ce qui ne va pas : Le test porte sur la gestion d'une session côté serveur (déconnexion après inactivité, avertissement, prolongation). Rien de tout cela n'est démontrable dans une page statique servie par nginx : il faudrait un backend avec état.

Comment corriger : En conditions réelles : prévenir l'utilisateur avant l'expiration, proposer de prolonger la session, et ne jamais perdre les données saisies.

WCAG :
  • 2.2.1 Timing adjustable (A)
  • 2.2.2 Pause, Stop, Hide (A)

13.2 — Dans chaque page web, l'ouverture d'une nouvelle fenêtre ne doit pas être déclenchée sans action de l'utilisateur. Cette règle est-elle respectée ?

13.2.1 manuel

Dans chaque page web, l'ouverture d'une nouvelle fenêtre ne doit pas être déclenchée sans action de l'utilisateur. Cette règle est-elle respectée ?

Démo volontairement fautive

Voir le code source du piège
<input type='text' placeholder='Votre nom' onfocus='window.open("aide.html")'>

Ce qui ne va pas : Le simple fait de recevoir le focus (toucher le champ au clavier ou au doigt) ouvre une nouvelle fenêtre, sans action explicite de l'utilisateur. Ce changement de contexte inattendu désoriente, notamment au clavier.

Comment corriger : Déclencher l'ouverture uniquement sur une action volontaire (clic sur un lien ou un bouton), et supprimer tout déclenchement par onfocus ou onload.

WCAG :
  • 3.2.1 On focus (A)

13.3 — Dans chaque page web, chaque document bureautique en téléchargement possède-t-il, si nécessaire, une version accessible (hors cas particuliers) ?

13.3.1 manuel

Dans chaque page web, chaque fonctionnalité de téléchargement d'un document bureautique vérifie-t-elle une de ces conditions ? Le document en téléchargement est compatible avec l'accessibilité ; Il existe une version alternative du document en téléchargement compatible avec l'accessibilité ; Il existe une version alternative du document en téléchargement au format HTML.

Démo volontairement fautive

Voir le code source du piège
<a href='notice.pdf'>Télécharger la notice (PDF)</a>

Ce qui ne va pas : Le document bureautique proposé au téléchargement n'est pas accompagné d'une version accessible (PDF balisé, DOCX accessible ou version HTML) offrant la même information. Un PDF non balisé est illisible pour les lecteurs d'écran.

Comment corriger : Proposer à côté du fichier une version alternative accessible, par exemple : <a href="notice.html">Consulter la notice en ligne (HTML)</a>.

WCAG :
  • 1.1.1 Non-text Content (A)
  • 1.3.1 Info and Relationships (A)
  • 1.3.2 Meaningful Sequence (A)
  • 2.4.1 Bypass Blocks (A)
  • 2.4.3 Focus Order (A)
  • 3.1.1 Language of Page (A)
  • 4.1.2 Name, Role, Value (A)

13.4 — Pour chaque document bureautique ayant une version accessible, cette version offre-t-elle la même information ?

13.4.1 manuel

Chaque document bureautique ayant une version accessible vérifie-t-il une de ces conditions ? La version compatible avec l'accessibilité offre la même information ; La version alternative au format HTML est pertinente et offre la même information.

Démo volontairement fautive

Voir le code source du piège
<a href='notice.pdf'>Notice complète (PDF)</a> <a href='resume.html'>Version accessible</a>

Ce qui ne va pas : La version dite « accessible » (HTML) n'est qu'un résumé : elle n'offre pas la même information que le document original. Une version alternative doit être équivalente en contenu, pas un extrait.

Comment corriger : Veiller à ce que la version alternative (HTML ou PDF balisé) reprenne l'intégralité de l'information du document original, à l'identique.

WCAG :
  • 1.1.1 Non-text Content (A)
  • 1.3.1 Info and Relationships (A)
  • 1.3.2 Meaningful Sequence (A)
  • 2.4.1 Bypass Blocks (A)
  • 2.4.3 Focus Order (A)
  • 3.1.1 Language of Page (A)
  • 4.1.2 Name, Role, Value (A)

13.5 — Dans chaque page web, chaque contenu cryptique (art ASCII, émoticône, syntaxe cryptique) a-t-il une alternative ?

13.5.1 manuel

Dans chaque page web, chaque contenu cryptique (art ASCII, émoticône, syntaxe cryptique) vérifie-t-il une de ces conditions ? Un attribut title est disponible ; Une définition est donnée par le contexte adjacent.

Démo volontairement fautive

Résultat : :-)

¯\_(ツ)_/¯

Voir le code source du piège
<p>Résultat : :-) <pre>¯\_(ツ)_/¯</pre></p>

Ce qui ne va pas : L'émoticône « :-) » et l'art ASCII n'ont ni attribut title ni définition donnée par le contexte adjacent. Un lecteur d'écran lit ces caractères un par un ou les ignore, et leur sens est perdu.

Comment corriger : Donner une alternative textuelle : ajouter un attribut title (« content ») ou expliciter le sens dans le contexte, par exemple « Résultat : content ».

WCAG :
  • 1.1.1 Non-text Content (A)

13.6 — Dans chaque page web, pour chaque contenu cryptique (art ASCII, émoticône, syntaxe cryptique) ayant une alternative, cette alternative est-elle pertinente ?

13.6.1 manuel

Dans chaque page web, chaque contenu cryptique (art ASCII, émoticône, syntaxe cryptique) vérifie-t-il une de ces conditions ? Le contenu de l'attribut title est pertinent ; La définition donnée par le contexte adjacent est pertinente.

Démo volontairement fautive

:-)

Voir le code source du piège
<p title='symbole'>:-)</p>

Ce qui ne va pas : L'alternative fournie via l'attribut title (« symbole ») est trop vague : elle ne restitue pas le sens du contenu cryptique. L'utilisateur comprend qu'il s'agit d'un symbole mais pas ce qu'il signifie.

Comment corriger : Rendre l'alternative pertinente : <p title="content">:-)</p>, ou expliquer le sens dans le contexte adjacent.

WCAG :
  • 1.1.1 Non-text Content (A)

13.7 — Dans chaque page web, les changements brusques de luminosité ou les effets de flash sont-ils correctement utilisés ?

13.7.1 manuel

Dans chaque page web, chaque image ou élément multimédia (balise <video>, balise <img>, balise <svg>, balise <canvas>, balise <embed> ou balise <object>) qui provoque un changement brusque de luminosité ou un effet de flash vérifie-t-il une de ces conditions ? La fréquence de l'effet est inférieure à 3 par seconde ; La surface totale cumulée des effets est inférieure ou égale à 21824 pixels.

Démo volontairement fautive

Voir le code source du piège
<svg width='300' height='100'><rect width='300' height='100' fill='#fff'><animate attributeName='fill' values='#ffffff;#000000' dur='0.2s' repeatCount='indefinite'></animate></rect></svg>

Ce qui ne va pas : Ce contenu SVG alterne blanc et noir environ 5 fois par seconde : la fréquence du flash dépasse 3 par seconde et la surface cumulée (30 000 pixels) dépasse 21 824 pixels. Ces deux conditions réunies peuvent déclencher des crises d'épilepsie photosensible.

Comment corriger : Supprimer l'effet de flash ou, à défaut, respecter les deux seuils : fréquence inférieure à 3 par seconde ET surface cumulée inférieure ou égale à 21 824 pixels.

WCAG :
  • 2.3.1 Three Flashes or Below Threshold (A)

13.7.2 n/a

Dans chaque page web, chaque script qui provoque un changement brusque de luminosité ou un effet de flash vérifie-t-il une de ces conditions ? La fréquence de l'effet est inférieure à 3 par seconde ; La surface totale cumulée des effets est inférieure ou égale à 21824 pixels.

Démo volontairement fautive

Non démontrable en page statique — voir l'explication ci-dessous.

Ce qui ne va pas : Le test porte sur des scripts qui provoquent un changement brusque de luminosité ou un effet de flash (par exemple une animation JavaScript de la couleur de fond). Un script exécutable n'est pas démontrable dans une page statique sans code JavaScript.

Comment corriger : En conditions réelles : vérifier la fréquence (moins de 3 flashs par seconde) et la surface cumulée (inférieure ou égale à 21 824 pixels) de tout effet produit par script.

WCAG :
  • 2.3.1 Three Flashes or Below Threshold (A)

13.7.3 manuel

Dans chaque page web, chaque mise en forme CSS qui provoque un changement brusque de luminosité ou un effet de flash vérifie-t-elle une de ces conditions ? La fréquence de l'effet est inférieure à 3 par seconde ; La surface totale cumulée des effets est inférieure ou égale à 21824 pixels.

Démo volontairement fautive

Alerte importante

Voir le code source du piège
<style>@keyframes flash-css { 50% { opacity: 0; } }</style> <p style='animation: flash-css 0.25s infinite'>Alerte importante</p>

Ce qui ne va pas : Cette animation CSS fait clignoter le texte 4 fois par seconde : la fréquence dépasse 3 flashs par seconde et peut provoquer des crises chez les personnes photosensibles. Aucun contrôle ne permet de l'arrêter.

Comment corriger : Retirer l'animation ou la limiter à moins de 3 cycles par seconde avec une surface cumulée inférieure à 21 824 pixels ; proposer de préférence un contenu statique.

WCAG :
  • 2.3.1 Three Flashes or Below Threshold (A)

13.8 — Dans chaque page web, chaque contenu en mouvement ou clignotant est-il contrôlable par l'utilisateur ?

13.8.1 axe · marquee

Dans chaque page web, chaque contenu en mouvement déclenché automatiquement, vérifie-t-il une de ces conditions ? La durée du mouvement est inférieure ou égale à 5 secondes ; L'utilisateur peut arrêter et relancer le mouvement ; L'utilisateur peut afficher et masquer le contenu en mouvement ; L'utilisateur peut afficher la totalité de l'information sans le mouvement.

Démo volontairement fautive

Bienvenue sur notre site
Voir le code source du piège
<marquee>Bienvenue sur notre site</marquee>

Ce qui ne va pas : Ce contenu défile en continu, automatiquement, sans aucun contrôle : l'utilisateur ne peut ni l'arrêter, ni le relancer, ni le masquer, ni lire l'information sans le mouvement. Le mouvement permanent est également très gênant pour les personnes souffrant de troubles de l'attention.

Comment corriger : Remplacer le <marquee> par un contenu statique, ou fournir des boutons d'arrêt/relance et la possibilité d'afficher l'information sans mouvement.

WCAG :
  • 2.2.1 Timing Adjustable (A)
  • 2.2.2 Pause, Stop, Hide (A)

13.8.2 axe · blink

Dans chaque page web, chaque contenu clignotant déclenché automatiquement, vérifie-t-il une de ces conditions ? La durée du clignotement est inférieure ou égale à 5 secondes ; L'utilisateur peut arrêter et relancer le clignotement ; L'utilisateur peut afficher et masquer le contenu clignotant ; L'utilisateur peut afficher la totalité de l'information sans le clignotement.

Démo volontairement fautive

Promotion : -50 %
Voir le code source du piège
<blink>Promotion : -50 %</blink>

Ce qui ne va pas : Ce texte clignote en continu de façon automatique, sans contrôle utilisateur. Le clignotement est impossible à arrêter, à relancer ou à masquer, et l'information est illisible pendant les phases éteintes.

Comment corriger : Remplacer le <blink> par un contenu statique ou par un mécanisme contrôlable (boutons d'arrêt/relance). Le clignotement n'a pas sa place pour du texte informatif : préférer une mise en évidence statique (gras, encadré).

WCAG :
  • 2.2.1 Timing Adjustable (A)
  • 2.2.2 Pause, Stop, Hide (A)

13.9 — Dans chaque page web, le contenu proposé est-il consultable quelle que soit l'orientation de l'écran (portrait ou paysage) (hors cas particuliers) ?

13.9.1 manuel

Dans chaque page web, chaque contenu vérifie-t-il ces conditions (hors cas particuliers) ? La consultation est possible quel que soit le mode d'orientation de l'écran ; Le contenu proposé reste le même quel que soit le mode d'orientation de l'écran utilisé même si sa présentation et le moyen d'y accéder peut différer.

Démo volontairement fautive

Voir le code source du piège
<style>@media (orientation: portrait) { html { transform: rotate(90deg); } }</style>

Ce qui ne va pas : Cette règle CSS force la rotation du contenu en orientation portrait : la consultation n'est plus naturelle dans les deux orientations. La règle axe css-orientation-lock est expérimentale et n'est pas exécutée par ally-agent : contrôle manuel.

Comment corriger : Supprimer ce verrouillage et laisser le contenu s'adapter librement aux deux orientations (portrait et paysage), sans rotation imposée. Utiliser des mises en page fluides (grilles, unités relatives).

WCAG :
  • 1.3.4 Orientation (AA)

13.10 — Dans chaque page web, les fonctionnalités utilisables ou disponibles au moyen d'un geste complexe peuvent-elles être également disponibles au moyen d'un geste simple (hors cas particuliers) ?

13.10.1 n/a

Dans chaque page web, chaque fonctionnalité utilisable ou disponible suite à un contact multipoint est-elle également utilisable ou disponible suite à un contact en un point unique de l'écran (hors cas particuliers).

Démo volontairement fautive

Non démontrable en page statique — voir l'explication ci-dessous.

Ce qui ne va pas : Le test porte sur les fonctionnalités déclenchées par un contact multipoint (deux doigts ou plus, comme le pincement pour zoomer). De tels gestes nécessitent du code JavaScript et un écran tactile : non démontrables dans une page statique.

Comment corriger : En conditions réelles : proposer une alternative en geste simple (un seul point de contact), par exemple des boutons « Zoom + / Zoom − » en plus du pincement.

WCAG :
  • 2.5.1 Pointer Gestures (A)

13.10.2 n/a

Dans chaque page web, chaque fonctionnalité utilisable ou disponible suite à un geste basé sur le suivi d'une trajectoire sur l'écran est-elle également utilisable ou disponible suite à un contact en un point unique de l'écran (hors cas particuliers).

Démo volontairement fautive

Non démontrable en page statique — voir l'explication ci-dessous.

Ce qui ne va pas : Le test porte sur les fonctionnalités déclenchées par un geste basé sur une trajectoire (glisser-déposer, balayage). Ces interactions exigent du code JavaScript et un écran tactile : non démontrables dans une page statique.

Comment corriger : En conditions réelles : proposer une alternative en geste simple, par exemple des boutons de déplacement ou de validation en plus du glisser-déposer.

WCAG :
  • 2.5.1 Pointer Gestures (A)

13.11 — Dans chaque page web, les actions déclenchées au moyen d'un dispositif de pointage sur un point unique de l'écran peuvent-elles faire l'objet d'une annulation (hors cas particuliers) ?

13.11.1 manuel

Dans chaque page web, les actions déclenchées au moyen d'un dispositif de pointage sur un point unique de l'écran vérifient-elles l'une de ces conditions (hors cas particuliers) ? L'action est déclenchée au moment où le dispositif de pointage est relâché ou relevé ; L'action est déclenchée au moment où le dispositif de pointage est pressé ou posé puis annulée lorsque le dispositif de pointage est relâché ou relevé ; Un mécanisme est disponible pour abandonner (avant achèvement de l'action) ou annuler (après achèvement) l'exécution de l'action.

Démo volontairement fautive

Voir le code source du piège
<form action='valider.html'><button type='submit' onmousedown='this.form.submit()'>Envoyer</button></form>

Ce qui ne va pas : L'action est déclenchée dès l'appui sur le bouton (onmousedown) : l'utilisateur ne peut pas annuler en glissant le doigt ou la souris hors du bouton avant de relâcher. Les actions doivent être déclenchées au relâchement ou être annulables.

Comment corriger : Laisser le déclenchement natif se produire au relâchement (click), ou proposer un mécanisme d'annulation (bouton « Annuler »).

WCAG :
  • 2.5.2 Pointer Cancellation (A)

13.12 — Dans chaque page web, les fonctionnalités qui impliquent un mouvement de l'appareil ou vers l'appareil peuvent-elles être satisfaites de manière alternative (hors cas particuliers) ?

13.12.1 n/a

Dans chaque page web, les fonctionnalités disponibles en bougeant l'appareil peuvent-elles être accomplies avec des composants d'interface utilisateur (hors cas particuliers) ?

Démo volontairement fautive

Non démontrable en page statique — voir l'explication ci-dessous.

Ce qui ne va pas : Le test porte sur les fonctionnalités déclenchées par le mouvement de l'appareil (secouer, incliner le téléphone). Cela nécessite les capteurs de l'appareil et du code JavaScript : non démontrable dans une page statique.

Comment corriger : En conditions réelles : proposer des composants d'interface équivalents (boutons, liens) pour déclencher les mêmes actions sans bouger l'appareil.

WCAG :
  • 2.5.4 Motion Actuation (A)

13.12.2 n/a

Dans chaque page web, les fonctionnalités disponibles en faisant un geste en direction de l'appareil peuvent-elles être accomplies avec des composants d'interface utilisateur (hors cas particuliers) ?

Démo volontairement fautive

Non démontrable en page statique — voir l'explication ci-dessous.

Ce qui ne va pas : Le test porte sur les fonctionnalités déclenchées par un geste en direction de l'appareil (pointer la caméra, s'approcher de l'écran). Cela nécessite des capteurs et du code JavaScript : non démontrable dans une page statique.

Comment corriger : En conditions réelles : proposer des composants d'interface équivalents (boutons, liens) pour accomplir les mêmes actions sans geste vers l'appareil.

WCAG :
  • 2.5.4 Motion Actuation (A)

13.12.3 n/a

L'utilisateur a-t-il la possibilité de désactiver la détection du mouvement pour éviter un déclenchement accidentel de la fonctionnalité (hors cas particuliers) ?

Démo volontairement fautive

Non démontrable en page statique — voir l'explication ci-dessous.

Ce qui ne va pas : Le test porte sur la possibilité de désactiver la détection du mouvement pour éviter les déclenchements accidentels. Cette détection repose sur les capteurs de l'appareil et du code JavaScript : non démontrable dans une page statique.

Comment corriger : En conditions réelles : proposer un réglage (par exemple un interrupteur) permettant de désactiver la détection du mouvement.

WCAG :
  • 2.5.4 Motion Actuation (A)