PD-230 — Retour d'expérience¶
📚 Navigation User Story
| Document | | | ---------- | -- | | 📋 [Spécification](PD-230-specification.md) | | | 🛠️ [Plan d'implémentation](PD-230-plan.md) | | | ✅ [Critères d'acceptation](PD-230-acceptability.md) | | | 📝 **Retour d'expérience** | *(ce document)* | [← Retour à site-vitrine](../PD-225-epic.md) · [↑ Index User Story](index.md)1. Résumé exécutif¶
La User Story PD-230 visait à garantir la conformité WCAG 2.1 AA avec un focus sur les contrastes et la navigation clavier. L'implémentation a intégré des styles :focus-visible dans le design system et des aria-labels sur les liens sociaux du footer. Cependant, plusieurs écarts majeurs ont été identifiés : absence totale des outils de validation (eslint-plugin-astro/jsx-a11y, pa11y-ci), pas de skip link, navigation ARIA incomplète (pas d'aria-label sur nav, pas d'aria-expanded sur le menu mobile). Verdict : ACCEPTÉ AVEC RÉSERVES.
2. Points fluides¶
- Styles :focus-visible implémentés dans design-system.css avec outline visible
- Contrastes de la palette de couleurs respectant les ratios WCAG (vérification visuelle)
- Liens sociaux du footer avec aria-label explicite
- Structure HTML sémantique de base (header, nav, main, footer)
- Zones tactiles minimales 48px sur les boutons (WCAG 2.5.5)
- Liens avec padding pour augmenter la zone de clic
3. Points difficiles¶
-
Outillage a11y non mis en place : Ni eslint-plugin-astro/jsx-a11y ni pa11y-ci n'ont été installés ou configurés. Aucun test automatisé d'accessibilité n'existe.
-
Skip link absent : Le composant SkipLink.astro prévu dans le plan n'a pas été créé. Les utilisateurs clavier ne peuvent pas sauter directement au contenu principal.
-
Landmarks ARIA incomplets : La balise
<nav>n'a pas d'aria-label, le<main>n'a pas d'id="main-content", ce qui rend la navigation par landmarks moins efficace pour les lecteurs d'écran. -
Menu mobile non accessible : Le bouton hamburger n'a pas d'aria-expanded pour indiquer l'état ouvert/fermé aux technologies d'assistance.
4. Hypothèses révélées tardivement¶
-
Complexité de l'outillage a11y : L'intégration de pa11y-ci nécessite un serveur local pour tester les pages générées, ce qui ajoute de la complexité à la CI.
-
Navigation mobile nécessite JavaScript : Le menu mobile utilise JavaScript pour toggler les classes, ce qui impose de gérer aria-expanded dynamiquement en JS également.
-
Score AA vs conformité réelle : Passer un audit automatisé ne garantit pas la conformité totale. Les tests manuels (navigation clavier, lecteur d'écran) sont nécessaires.
5. Invariants complexes¶
| Invariant | Difficulté |
|---|---|
| Contraste minimum respecté | Facile avec les tokens de couleur bien choisis |
| Navigation clavier possible | Complexe : nécessite skip link, focus management, ARIA |
| Score AA validé | Non vérifiable sans outillage automatisé |
6. Dette technique¶
| Dette | Impact | Priorité |
|---|---|---|
| Pas de eslint-plugin-astro/jsx-a11y | Erreurs a11y non détectées | Haute |
| Pas de pa11y-ci | Pas de test automatisé WCAG | Haute |
| Pas de SkipLink.astro | Navigation clavier dégradée | Haute |
| nav sans aria-label | Lecteurs d'écran moins informatifs | Moyenne |
| main sans id="main-content" | Skip link impossible | Haute |
| Menu mobile sans aria-expanded | État non communiqué aux AT | Moyenne |
| Pas d'accessibility.css dédié | Styles a11y mélangés au design system | Basse |
7. Risques résiduels¶
| Risque | Probabilité | Impact | Mitigation suggérée |
|---|---|---|---|
| Non-conformité WCAG 2.1 AA réelle | Haute | Élevé | Audit manuel + pa11y-ci |
| Plainte accessibilité utilisateur | Faible | Moyen | Ajouter skip link, améliorer ARIA |
| Régressions a11y futures | Haute | Moyen | Intégrer eslint a11y en CI |
| Menu mobile inaccessible | Moyenne | Moyen | Ajouter aria-expanded + gestion focus |
8. Améliorations processus¶
- Installer l'outillage a11y en premier : eslint-plugin-astro/jsx-a11y et pa11y-ci avant d'écrire le premier composant
- Créer un checklist WCAG : Vérifier manuellement chaque composant contre les critères AA
- Tester avec un lecteur d'écran : VoiceOver/NVDA en test manuel avant livraison
- Séparer les styles a11y : Fichier accessibility.css dédié pour prefers-reduced-motion, skip links, etc.
- Documenter les patterns ARIA : Guide pour les développeurs sur l'utilisation correcte d'ARIA
9. Enseignements clés¶
-
L'accessibilité ne s'ajoute pas à la fin — Les patterns ARIA (aria-label, aria-expanded) doivent être pensés dès la conception du composant.
-
Les outils automatisés sont indispensables — Sans eslint a11y et pa11y-ci, les violations WCAG passent inaperçues jusqu'aux plaintes utilisateurs.
-
Le skip link est fondamental — C'est la première chose qu'un utilisateur clavier rencontre. Son absence dégrade significativement l'expérience.
-
Le focus visible ne suffit pas — Avoir un outline ne garantit pas une navigation clavier fluide. L'ordre de tabulation et les landmarks comptent aussi.
-
JavaScript et accessibilité doivent cohabiter — Si un composant utilise JS pour changer d'état visuel, il doit aussi mettre à jour les attributs ARIA correspondants.
10. Addendum — Résolution (2025-12-21)¶
Verdict final : ✅ ACCEPTÉ — Les écarts E-01, E-02 et E-03 ont été résolus.
Adaptations par rapport au plan initial¶
| Élément prévu | Adaptation | Justification |
|---|---|---|
eslint-plugin-astro/jsx-a11y | Remplacé par html-validate avec preset a11y | jsx-a11y ne parse pas la syntaxe template Astro (conçu pour JSX/React) |
pa11y.config.js | Remplacé par .pa11yci.json | pa11y-ci v4 ne supporte pas les fichiers JS en projet ESM ("type": "module") |
| Lint source | Lint HTML généré (post-build) | Plus fiable : valide le résultat final vu par l'utilisateur |
Dette technique résolue¶
| Dette | Statut | Résolution |
|---|---|---|
| Pas de eslint a11y | ✅ Résolu | html-validate avec preset html-validate:a11y |
| Pas de pa11y-ci | ✅ Résolu | .pa11yci.json + job CI a11y activé |
| Pas de SkipLink.astro | ✅ Résolu | src/components/SkipLink.astro créé |
| nav sans aria-label | ✅ Résolu | aria-label i18n ajouté dans Header.astro |
| main sans id="main-content" | ✅ Résolu | id="main-content" ajouté dans BaseLayout.astro |
| Menu mobile sans aria-expanded | ✅ Résolu | aria-expanded + aria-controls + JS toggle |
| Pas d'accessibility.css | ✅ Résolu | src/styles/accessibility.css (skip-link, reduced-motion, touch-targets) |
Risques résiduels post-résolution¶
| Risque | Probabilité | Impact | Statut |
|---|---|---|---|
| Non-conformité WCAG 2.1 AA | Moyenne | Élevé | Mitigé — Outillage en place, 103 erreurs de contraste détectées (hors périmètre PD-230) |
| Régressions a11y futures | Faible | Moyen | Mitigé — CI exécute lint:html + test:a11y |
Enseignement supplémentaire¶
- Vérifier la compatibilité des outils avec le framework —
eslint-plugin-jsx-a11yest conçu pour React/JSX, pas pour Astro. Toujours tester un plugin sur un fichier réel avant de l'inclure au plan d'implémentation.
Travaux restants (hors périmètre PD-230)¶
- Correction des contrastes : 103 erreurs
color-contrastdétectées par pa11y (Hero, CTA, badges, Brevo form). À traiter dans un ticket dédié design/tokens.