Aller au contenu principal

Pièce justificative en accessibilité

Rapport de conformité : WCAG 2.1 niveau AA

Revenir au site · Toutes les réalisations · Écrire pour un premier échange

Objets audités : deux versions du même contenu pédagogique.

Fichier Version
module-demo.html Version riche : simulateur d'annonce, comparaisons avant/après, exercice de repérage, animations
module-demo-sobre.html Version sobre : mise en page linéaire, une seule interaction

Référentiel : WCAG 2.1, niveau AA.

Portée (à lire avant le reste) : ce rapport couvre deux des neuf pièces du dossier de démonstration, et WCAG 2.1 seulement. Le Standard du gouvernement du Québec (SGQRI 008 3.0, en vigueur depuis le 29 avril 2024) exige WCAG 2.1 AA plus sept critères de WCAG 2.2 (3.2.6, 3.3.7, 2.4.11, 2.5.7, 2.5.8, 3.3.8 et 2.4.13). La section 4, ajoutée le 03/09/2026, n'en traite que deux : 2.5.7 (mouvements de glissement) et 2.5.8 (taille de cible). Les cinq autres n'ont pas été testés. L'une des deux pièces y semblait en échec ; la remesure du 30/10/2026 a montré que non (voir section 4).

Date de l'audit : 2026-07-27

Auditeur : Pierre Camille Gillet

Résumé

Volet Version riche Version sobre
Audit automatisé (axe-core 4.12.1) 0 violation 0 violation
Contrastes mesurés 20 paires au chargement, 0 échec (minimum 4,57:1) 14 paires, 0 échec (minimum 6,30:1)
Structure des titres 1 h1, aucun saut de niveau 1 h1, aucun saut de niveau
Éléments interactifs 13 boutons natifs, 0 élément non natif rendu cliquable 4 champs natifs
tabindex positif · outline:none 0 · 0 0 · 0
Dépendances externes Aucune Aucune

Pourquoi deux versions. Un contenu accessible n'est pas condamné à être austère. Les deux fichiers portent la même pédagogie et atteignent le même niveau de conformité ; ils démontrent que le choix esthétique et l'obligation légale sont deux questions séparées.

Une précision qui compte. Testés sur une page truffée d'obstacles, les outils automatisés en ont trouvé de 17 % à 41 % selon l'outil, et près d'un tiers n'a été repéré par aucun (gouvernement britannique, 2017). Un rapport qui ne présenterait que leur sortie serait une preuve incomplète. C'est pourquoi la section 2 existe.

Un défaut trouvé et corrigé en cours d'audit. Le premier passage sur la version riche a relevé trois violations de contraste sur les lignes de la démonstration animée du bandeau. Cette démonstration est masquée aux technologies d'assistance (aria-hidden), mais son texte reste lu à l'œil : le critère s'applique malgré tout. Couleur corrigée, contraste porté à 8,61:1, nouveau passage à zéro violation. Ce défaut est consigné plutôt qu'effacé : il illustre exactement le genre d'erreur qu'un audit sert à attraper.

1. Audit automatisé

Outil : axe-core 4.12.1, exécuté dans Chrome headless.

Portée : règles étiquetées wcag2a, wcag2aa, wcag21a, wcag21aa.

Résultat : 0 violations found! sur les deux fichiers. Rejoué le 18/09/2026, douze passages par fichier à des instants échelonnés du chargement : 0 violation sur les douze, pour chacun des deux (détail en section 5).

Ce que cet outil couvre bien : contrastes de texte, attributs manquants, étiquettes de formulaire absentes, structure de titres, rôles ARIA invalides, doublons d'identifiants.

Ce qu'il ne peut pas juger : la pertinence d'un texte alternatif, la cohérence de l'ordre de tabulation, le caractère compréhensible d'un intitulé, la qualité d'un message d'erreur, le comportement des composants interactifs. Section suivante.

2. Vérifications manuelles

Chaque ligne indique la méthode employée. Un critère marqué conforme sans méthode indiquée n'aurait aucune valeur.

Perception

Critère WCAG Méthode Résultat
1.1.1 Contenu non textuel (A) Inspection de chaque élément graphique. La démonstration animée du bandeau est décorative et porte aria-hidden="true" ; son contenu est intégralement repris, sous forme opérable, par le simulateur situé juste en dessous. Aucune information n'existe uniquement dans une image. Conforme
1.3.1 Information et relations (A) Extraction programmatique, recomptée sur le rendu le 18/09/2026 : 1 h1, 8 h2, 3 h3 (version sobre : 1, 9, 3), aucun saut de niveau. Listes en ul, groupes de boutons en role="group" avec aria-label, 8 sections nommées par aria-labelledby (9 dans la version sobre). Conforme
1.3.2 Ordre séquentiel logique (A) L'ordre du DOM suit l'ordre de lecture visuel, y compris dans la grille à deux colonnes du simulateur : le fragment précède la console qui le commente. Conforme
1.4.1 Utilisation de la couleur (A) Aucun état porté par la seule couleur : les panneaux avant/après portent un verdict écrit, les réponses de l'exercice reçoivent la mention « Trouvé » ou « Non », l'élément sélectionné du simulateur porte aria-pressed. Conforme
1.4.3 Contraste (minimum) (AA) Calcul du ratio de luminance relative sur les paires texte/fond effectivement rendues, page au chargement. Recompté le 18/09/2026 : 20 paires. Minimum relevé : 4,57:1 (texte d'attente de la console du simulateur, « Sélectionnez un élément… », gris translucide sur bleu nuit) ; la paire suivante est à 6,34:1 (surtitre ambre foncé sur fond brume). Seuil requis : 4,5:1. Le rapport annonçait jusqu'ici « 22 paires, minimum 6,34:1 » : la paire la plus basse n'y figurait pas. Conforme
1.4.4 Redimensionnement du texte (AA) Tailles en unités relatives (rem, clamp), aucune hauteur fixe sur un conteneur de texte. Zoom à 200 % sans perte. Conforme
1.4.10 Redistribution (AA) Grilles repassant sur une colonne sous 48 et 52 rem. Les blocs de code défilent horizontalement dans leur propre conteneur ; le corps de page ne défile jamais horizontalement. Conforme
1.4.11 Contraste du contenu non textuel (AA) Indicateur de focus mesuré dans ses deux variantes : contour encre sur fond clair 17,37:1, contour ambre sur fond sombre 9,48:1. Seuil requis : 3:1. Bordures des boutons et panneaux vérifiées. Conforme

Utilisation

Critère WCAG Méthode Résultat
2.1.1 Clavier (A) Tous les éléments interactifs sont des <button> natifs, 13 au total. Vérification programmatique : aucun div ou span porteur d'un gestionnaire de clic, aucun tabindex positif. Rien n'est atteignable à la souris qui ne le soit au clavier. Conforme
2.1.2 Pas de piège au clavier (A) Aucune fenêtre modale, aucun piège de focus. La console du simulateur est position: sticky, ce qui ne modifie pas l'ordre de tabulation. Conforme
2.2.2 Mettre en pause, arrêter, masquer (A) Relevé des animations en cours dans le navigateur (document.getAnimations()) à 1 s, 5,2 s et 7 s après le chargement, le 18/09/2026. Version riche : les trois cadres du bandeau s'allument une seule fois, l'un après l'autre, puis s'arrêtent sur un état fixe lisible (3 animations en cours à 1 s, 0 à 5,2 s, 0 à 7 s, aucune animation infinie) ; le texte du bandeau ne s'anime pas. Depuis le 31/10/2026, la séquence ne part que lorsque le bandeau est entièrement à l'écran et repart à chaque retour ; chaque passage dure toujours 4,3 s et s'arrête (relevé le 31/10/2026 : 3 animations à l'arrivée, 0 après 5,5 s), et rien ne bouge en mouvement réduit. Version sobre : 0 animation aux trois instants. Avant le 18/09/2026, le bandeau tournait en boucle (6 animations infinies, texte qui apparaissait et disparaissait) sans commande de pause : le critère n'était pas satisfait, et ce rapport ne le traitait pas. Conforme depuis le 18/09/2026
2.3.3 Animation résultant d’interactions (AAA, appliqué volontairement) Toutes les animations et transitions sont neutralisées sous prefers-reduced-motion: reduce, y compris la révélation au défilement, qui bascule en affichage direct. La démonstration du bandeau passe alors en état statique lisible. Conforme
2.4.1 Contourner des blocs (A) Lien d'évitement en première position, masqué hors focus, visible dès qu'il le reçoit. Conforme
2.4.2 Titre de page (A) <title> présent et descriptif. Conforme
2.4.3 Parcours du focus (A) L'ordre de tabulation suit l'ordre du DOM. Aucun déplacement de focus programmatique : les mises à jour passent par des régions live, jamais par un vol de focus. Conforme
2.4.4 Fonction du lien (selon le contexte) (A) Cinq liens réels, recomptés sur le rendu le 18/09/2026 : le lien d'évitement, le lien vers ce rapport, le lien vers l'autre version du module, « Retour à la présentation » et « Voir la démarche de conception ». L'intitulé de chacun énonce sa destination. Les intitulés fautifs présentés dans le contenu sont des exemples pédagogiques, non des liens actifs. Conforme
2.4.6 En-têtes et étiquettes (AA) Chaque titre décrit sa section. Les groupes de boutons avant/après portent un aria-label explicite. Chaque proposition de l'exercice est autoportante. Conforme
2.4.7 Visibilité du focus (AA) Style :focus-visible explicite (contour de 3 px, décalage, halo de 6 px), avec une variante dédiée aux sections sombres. Vérification programmatique : aucune occurrence de outline: none. Conforme

Compréhension et robustesse

Critère WCAG Méthode Résultat
3.1.1 Langue de la page (A) <html lang="fr-CA">. Aucun passage dans une autre langue. Conforme
3.2.2 À la saisie (A) Aucun changement de contexte automatique. Toute mise à jour découle d'une activation explicite et reste dans la même page. Conforme
3.3.1 Identification des erreurs (A) Dans l'exercice, une réponse incorrecte reçoit un verdict et une explication de ce qui ne va pas. Conforme
3.3.2 Étiquettes ou instructions (A) La consigne précède les choix dans les trois composants interactifs. Conforme
4.1.2 Nom, rôle et valeur (A) Boutons HTML natifs. Recompté sur le rendu le 18/09/2026 : 8 des 13 boutons portent aria-pressed (simulateur et comparaisons avant/après), mis à jour à chaque activation. Les 5 autres (les propositions de l'exercice de repérage) exposent leur état par le texte : la mention « Trouvé » ou « Non » s'écrit dans le bouton lui-même, donc dans son nom accessible. Aucun composant ARIA sur mesure. Conforme
4.1.3 Messages d'état (AA) Quatre régions role="status" avec aria-live="polite" : sortie du simulateur, deux panneaux de comparaison, score de l'exercice. Les mises à jour sont annoncées sans déplacer le focus ni interrompre la lecture en cours. Conforme

3. Ce qui n'a pas été vérifié

Cette section existe parce qu'un rapport sans limites serait suspect.

4. Passe du 03/09/2026 : critères WCAG 2.2 et rendu réel

Ce que la section 1 ne pouvait pas voir : les critères propres à WCAG 2.2, et les mesures faites sur le rendu (styles effectifs, tailles calculées) plutôt que sur le code. Outil : un navigateur sans interface (Chrome), axe-core 4.12.1 injecté, et un script qui mesure tailles et styles effectifs. Trois passages par pièce ; un constat n'est retenu que s'il est stable sur les trois.

Critère Version riche Version sobre
axe-core 4.12.1, règles 2.1 AA 0 violation (×3) 0 violation (×3)
2.5.8 Taille de cible, AA (WCAG 2.2) 0 🔴 3 non-conformités, stables : les trois boutons radio de la vérification (#rep-a, #rep-b, #rep-c) mesurent 18 × 18 px ; le critère exige 24 × 24, ou un espacement équivalent
2.5.7 Mouvements de glissement, AA (2.2) Sans objet (aucun glisser-déposer) Sans objet
1.3.1 hiérarchie de titres (rendu) 0 saut 0 saut
1.4.3 contraste, mesuré sur les styles effectifs 9 constats, stables. Jugés sur capture le 03/09 à 23 h 20 : faux positifs de l'outil. Le texte du bandeau est gris clair (185, 198, 211) sur bleu nuit, nettement lisible. L'outil résout le fond, composé de couches translucides, en valeurs hors gamme (« rgb(276, 293, 312) »), d'où un ratio absurde. Le 8,61:1 mesuré en juillet reste la mesure retenue 0
Texte < 12 px (heuristique de l'outil, pas un critère WCAG) 7 étiquettes à 11 px (span.tag) 0
Textes dans un SVG Sans objet (aucun SVG) 3 textes non jugés par l'outil (contraste à vérifier à l'œil)

Ce qui est établi : la version sobre n'est pas conforme au SGQRI 008 3.0 sur le critère 2.5.8. La correction est triviale (agrandir les cibles ou leur zone cliquable à 24 px) et n'a pas été faite dans cette passe. Ce rapport constate, il ne retouche pas la pièce.

Correction du 18/09/2026 : les trois boutons radio ont été portés à 24 × 24 px. Mesure faite sur le rendu, dans le navigateur (getBoundingClientRect sur #rep-a, #rep-b, #rep-c) : 24 × 24 sur les trois. La passe outillée du 03/09 n'a pas été rejouée depuis ; le constat ci-dessus est laissé tel quel, parce qu'un rapport qui efface ses défauts trouvés ne prouve plus rien.

Remesure du 30/10/2026 : ce constat était faux. Le critère 2.5.8 accepte une cible de moins de 24 px si un cercle de 24 px centré sur elle ne touche aucune autre cible, ni le cercle d'une autre petite cible. Sur la version d'avant correction, dans Chrome, à 1280 comme à 390 px de large, chaque bouton de 18 px était à 36,9 px au moins de la cible voisine la plus proche. L'exception d'espacement s'appliquait : les trois boutons étaient conformes. La passe du 03/09 avait mesuré la taille, pas l'espacement. Le passage à 24 px reste, par prudence.

Ce qui a failli être un faux constat : les 9 « contrastes insuffisants » de la version riche. L'outil les a rendus stables sur trois passages ; la capture les a démentis en une seconde. Un chiffre d'outil, même répété, n'est pas une mesure tant qu'on n'a pas regardé la page. Le défaut de l'outil (fonds translucides mal composés) est signalé à part ; il n'est pas corrigé dans cette passe.

Les sept autres pièces du dossier (capsule, étude de cas, exemple Rise, parcours à paliers, simulation, panorama 360, revue IA) ont reçu la même passe le 03/09 ; leurs résultats sont conservés à part et ne font pas partie de ce rapport. Un constat s'y est révélé instable (taille de cible sur le panorama : 7 puis 0 puis 0). Il n'est pas retenu, et c'est une raison de plus de ne jamais citer un chiffre d'outil sans l'avoir rejoué.

5. Passe du 18/09/2026 : ce qui a été rejoué

Un audit externe du 18/09/2026 a relevé que le critère 2.2.2 manquait à ce rapport et que cinq de ses chiffres ne se retrouvaient pas sur le rendu. Ce qui suit a été rejoué le même jour, dans Chrome sans interface, fenêtre de 1280 × 900, avec axe-core 4.12.1 injecté dans la page.

6. Modifications du 30/10/2026, remesurées par l'outil automatique

Les deux modules ont changé après la passe du 18/09, pour la forme seulement :

axe-core 4.12.1 a été relancé le 30/10/2026 sur les deux versions, à 1440 et à 390 px de large : 0 violation. Les vérifications manuelles des sections précédentes n'ont pas été refaites.

Annexe : reproduire cet audit

L'audit se rejoue en une commande. Le client n'a pas à croire ce rapport sur parole.

npm install -g @axe-core/cli
axe "file:///chemin/vers/module-demo.html" \
    --tags wcag2a,wcag2aa,wcag21a,wcag21aa,wcag22aa

Résultat attendu : 0 violations found!. Le 18/09/2026, ce résultat a été obtenu douze fois sur douze par fichier, avec axe-core injecté dans Chrome sans interface (section 5). La commande ci-dessus, elle, n'a pas été relancée ce jour-là. À savoir : axe-core a une règle pour la taille de cible (2.5.8), target-size. Elle est désactivée par défaut ; l'étiquette wcag22aa de la commande ci-dessus l'active. Certains cas lui restent « à revoir » : ceux-là se vérifient sur le rendu, à la main ou avec un outil qui calcule les tailles effectives.

Note d'exécution : si le pilote de navigateur ne correspond pas à la version de Chrome installée, poser la version correspondante (npm install -g chromedriver@<version majeure de Chrome>) et l'indiquer par l'option --chromedriver-path.