Aller au contenu principal
5.4

Accessibilité

WCAG 2.2 AA, CVD-safe, focus visible

Gradly vise WCAG 2.2 niveau AA sur l’ensemble du site et du produit. L’accessibilité n’est pas une option : c’est une exigence du cahier des charges Qualiopi (indicateur 26, référent handicap) que nos clients CFA doivent respecter.

Principes de base

Texte et contraste

Voir aussi 4.4 Palette règles pour la hiérarchie des couleurs textuelles.

  • Texte normal : minimum 4.5:1 avec le fond.
  • Texte large (18 px+ ou 14 px gras) : minimum 3:1.
  • Composants UI (bordures, icônes porteuses d’info) : minimum 3:1.
  • Tester les nouvelles combinaisons avec WebAIM Contrast Checker.

Ne jamais utiliser la couleur seule

Toute information véhiculée par la couleur (succès/échec, sélection, état) doit aussi être signalée par une icône, un texte, ou un motif. Règle CVD-safe universelle.

Focus visible

Tout élément interactif (lien, bouton, input, élément tabindex) doit avoir un outline bleu visible quand il reçoit le focus clavier.

Règle CSS globale dans src/styles/global.css :

a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--color-primary-500);
  outline-offset: 2px;
  border-radius: 4px;
}

/* Masque l'outline pour les utilisateurs souris, le garde pour clavier */
a:focus:not(:focus-visible),
button:focus:not(:focus-visible) {
  outline: none;
}

Règles :

  • Outline bleu primary-500 (2 px), offset 2 px
  • border-radius: 4px pour cohérence visuelle
  • Appliqué via :focus-visible (seulement clavier/assistance, pas au clic souris)

Un lien “Aller au contenu” est le premier élément focusable de chaque page. Il permet à l’utilisateur clavier/lecteur d’écran de sauter la navigation.

<a href="#main-content" class="sr-only focus:not-sr-only focus:absolute focus:top-4
  focus:left-4 focus:z-[100] focus:bg-blue-600 focus:text-white
  focus:px-4 focus:py-2 focus:rounded-lg">
  Aller au contenu principal
</a>

Visible uniquement quand il reçoit le focus, sinon masqué via sr-only.

Sémantique HTML

  • Un seul H1 par page (le titre principal de la page).
  • Hiérarchie stricte : pas de H3 sans H2 parent, pas de H4 sans H3, etc.
  • <main>, <nav>, <footer>, <article>, <section> utilisés selon leur sens.
  • <button> pour les actions, <a> pour les navigations. Jamais un <div onclick> habillé en bouton.

ARIA

Utiliser ARIA seulement quand HTML natif ne suffit pas. Premier réflexe : sémantique native. Deuxième réflexe : ARIA.

Usages fréquents sur le site Gradly

AttributUsage
aria-labelBouton icon-only (ex. fermer, menu)
aria-labelledbySection référencée par un titre déjà visible
aria-describedbyFormulaire avec message d’aide
aria-current="page"Lien du menu vers la page courante
aria-expandedBouton qui ouvre/ferme un contenu (menu mobile)
aria-hidden="true"Icône décorative (avec texte adjacent qui porte le sens)
role="alert" / role="status"Message dynamique de résultat de formulaire

Lecteurs d’écran (tests manuels)

Bien que l’outillage (Lighthouse, axe-core) automatise beaucoup, certains défauts ne sont détectables qu’en écoutant le site avec un vrai lecteur d’écran.

Tests minimum :

  • NVDA sur Firefox (Windows) — open source, gratuit, référence
  • VoiceOver sur Safari (macOS) — intégré

Scénarios à tester :

  1. Navigation au clavier (Tab, Shift+Tab, Enter, Space) : est-ce que je peux tout faire ?
  2. Formulaire de contact : les messages d’erreur sont-ils annoncés ?
  3. Menu mobile : le focus est-il piégé dedans quand ouvert ? sort-il avec Escape ?
  4. Liens “en savoir plus” génériques : les lecteurs d’écran peuvent lister tous les liens d’une page ; des “en savoir plus” sans contexte sont inutilisables.

Motion et accessibilité

Voir 5.3 Motion : toutes les animations respectent prefers-reduced-motion globalement.

Formulaires

  • Label visible pour chaque champ (<label for="email">Email</label>).
  • required natif sur les champs obligatoires (pas juste aria-required).
  • Indication * + texte “obligatoire” si le champ est requis (CNIL : pas de distinction uniquement par la couleur).
  • Messages d’erreur liés au champ via aria-describedby, avec role="alert" pour qu’ils soient lus dynamiquement.
  • Honeypot invisible + time-trap pour la lutte antispam (géré sur le site Gradly).

Responsable accessibilité

Pierre est actuellement le référent accessibilité Gradly. Pas de DAS (délégation d’accessibilité) formalisée tant que l’équipe reste à une personne. L’objectif de conformité WCAG 2.2 AA est suivi au long cours via les rounds d’audit (11 rounds complets à date, voir Historique des audits).

Pour signaler un problème d’accessibilité : voir 7.5 Contact.