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.
- Test avec un lecteur d'écran réel (VoiceOver, NVDA, JAWS). Les vérifications portent sur le code et sur des mesures ; elles ne remplacent pas une écoute réelle. Étape recommandée avant toute mise en ligne.
- Test avec des personnes en situation de handicap. La conformité technique n'est pas l'utilisabilité. Un contenu peut satisfaire tous les critères et rester pénible à parcourir.
- Critères sans objet ici : médias temporels (aucune vidéo ni audio), tableaux de données, contenu clignotant, expiration de session, navigation multi-pages, saisie de données personnelles.
- Niveau AAA : hors périmètre, à l'exception du critère 2.3.3 traité volontairement. Le SGQRI 008 3.0 exige le niveau AA (moins deux critères sur les médias) et quatre critères AAA : 2.3.2, 3.1.4, 2.5.6 et 2.4.13. Le premier est sans objet ici (aucun contenu clignotant) ; les trois autres n'ont pas été testés.
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.
- Bandeau de la version riche corrigé : il ne tourne plus en boucle (critère 2.2.2, section 2).
- axe-core, douze passages par fichier, lancés entre 0,3 s et 5,3 s après le chargement, règles
wcag2a,wcag2aa,wcag21a,wcag21aa,wcag22aa: 0 violation sur 12 pour la version riche, 0 sur 12 pour la version sobre. Le même protocole sur la version riche d'avant correction levait un contraste insuffisant 1 fois sur 12, pendant le fondu du texte du bandeau ; ce fondu n'existe plus. - Cinq chiffres recomptés sur le rendu et corrigés dans le résumé et la section 2 : nombre de
h2(8, et non 10), nombre de liens réels (5, et non 1), boutons portantaria-pressed(8 sur 13, et non 13), paires de contraste (20, minimum 4,57:1, et non 22, minimum 6,34:1), et la promesse de l'annexe, désormais assortie de son protocole. - Retrouvés à l'identique : version sobre, 14 paires, minimum 6,30:1 ; 13 boutons natifs,
0 élément non natif cliquable, 0
tabindexpositif, 0outline:none; 4 régionsrole="status". - Non rejoué le 18/09 : le zoom à 200 % (1.4.4), les mesures de l'indicateur de focus (1.4.11), la passe outillée du 03/09 (section 4). Les contrastes sont mesurés page au chargement ; les états après interaction sont couverts par axe-core, pas par le décompte des paires.
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 :
- Étiquettes : les étiquettes en capitales espacées sont passées en minuscules, en police sans empattement, à 0,875 rem au moins (aucune n'a rapetissé). Aucune couleur n'a changé : les paires de contraste mesurées le 18/09 sont les mêmes.
- Bande de navigation ajoutée en haut de chaque module, avec trois liens : « Pierre Camille Gillet », « Toutes les réalisations », « Écrire pour un premier échange ». Chaque version compte donc 8 liens réels sur le rendu, et non plus 5 (critère 2.4.4, section 2). Le lien « Retour à la présentation » s'appelle désormais « Revenir au site ».
- Guillemets : espaces insécables à l'intérieur, pour qu'aucun guillemet ne reste seul en fin de ligne.
- Appel de fin ajouté au bas de chaque version, avec deux liens : un vers le courriel, un vers la prise de rendez-vous. Chaque version compte donc 10 liens réels sur le rendu.
- Lien d'évitement de la version sobre replacé en tête de page, avant la bande de navigation.
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.