WordPress
23 avril 2025

Accessibilité web : pourquoi et comment rendre votre site inclusif pour tous ?

Accessibilité web : pourquoi et comment rendre votre site inclusif pour tous

Cet article a été écrit avant l’échéance de juin 2025 et en parlait au futur. Quatorze mois plus tard, l’obligation est en vigueur, les premières assignations sont tombées, et le sujet a changé de nature : il ne s’agit plus de se préparer mais de constater où on en est.

Le voici remis à jour, avec une correction importante sur le référentiel réellement applicable aux e-commerçants, et surtout la partie que les guides d’accessibilité n’abordent jamais : le problème principal d’une boutique en ligne est invisible pour tous les outils automatiques. Il se joue dans l’AJAX du panier, et le thème par défaut de PrestaShop 9 contient du code écrit exprès pour le traiter.

Au programme :

  • Ce qui a changé depuis l’entrée en vigueur, sanctions et premières poursuites comprises
  • Pourquoi le RGAA n’est pas exactement votre référentiel
  • Ce que Wave, Lighthouse et axe ne peuvent structurellement pas détecter
  • Le code d’accessibilité de PrestaShop 9, et ce qu’il révèle du vrai sujet
  • Le protocole de test qui attrape ce que les outils ratent

Ce qui a changé depuis juin 2025

L’European Accessibility Act est applicable depuis le 28 juin 2025. Pour la France, quelques repères concrets plutôt que des généralités.

Qui est concerné. Les services de commerce électronique, ainsi que la banque, les transports et les télécommunications. Sont exemptées les seules microentreprises, définies comme employant moins de 10 personnes et réalisant moins de 2 millions d’euros de chiffre d’affaires annuel ou de total de bilan. Les deux conditions, pas l’une ou l’autre.

Ce que vous risquez. Le plafond de sanction est de 250 000 euros en France. Mais le risque immédiat n’est pas administratif, il est judiciaire et réputationnel.

Ce qui s’est passé depuis. En juillet 2025, des associations ont adressé des mises en demeure à quatre enseignes de la distribution alimentaire au sujet de leurs services de courses en ligne. Les réponses ayant été jugées insuffisantes, des procédures en référé ont été engagées en novembre 2025 par les associations ApiDV et Droit Pluriel. La DGCCRF a par ailleurs adressé ses propres injonctions à la même période. Ce sont les premières actions de ce type en Europe sur le fondement de l’EAA.

Deux enseignements pour un e-commerçant. D’abord, le contrôle ne vient pas nécessairement d’une administration, il peut venir d’une association qui teste votre tunnel et constate qu’il est impraticable. Ensuite, l’attention s’est portée sur les tunnels de commande, pas sur les pages institutionnelles. C’est cohérent avec ce qui suit.

Le référentiel n’est pas celui qu’on croit

La version précédente de cet article indiquait qu’un e-commerçant devait « suivre le RGAA ». C’est un raccourci qui mérite d’être défait, parce qu’il fait chercher au mauvais endroit.

Le RGAA est le référentiel français d’application obligatoire pour le secteur public, les organismes délégataires d’une mission de service public, et les entreprises privées dépassant 250 millions d’euros de chiffre d’affaires, au titre de l’article 47 de la loi de 2005.

Pour un e-commerçant relevant de l’EAA, la référence technique est la norme européenne EN 301 549, dans sa version 3.2.1, qui intègre les WCAG 2.1 niveau AA pour la partie web. En pratique, comme le RGAA 4.1.2 est lui-même une transposition des WCAG 2.1 AA, s’appuyer dessus pour la partie web est une manière parfaitement valable de démontrer sa conformité, et c’est l’outil le plus commode en français.

La nuance n’est pas cosmétique : l’EN 301 549 couvre un périmètre plus large que le web seul, et les obligations déclaratives ne sont pas identiques à celles du secteur public. Dire « je suis conforme RGAA » et dire « je suis conforme EAA » ne sont pas la même phrase.

Ce que les outils automatiques ne peuvent pas voir

Wave, Lighthouse et axe sont d’excellents outils, et cet article en donnait une liste utile. Mais il faut comprendre ce qu’ils font : ils analysent un état figé du document. Ils vérifient qu’un alt est présent, qu’un contraste est suffisant, qu’un champ a un label.

Or l’essentiel d’un parcours d’achat ne se passe pas dans un état figé. Il se passe entre deux états : après un ajout au panier, après une modification de quantité, après l’ouverture d’une fenêtre modale, après l’application d’un filtre. C’est là que se produisent les défaillances les plus graves, et elles sont d’une nature particulière : elles ne cassent rien de visible.

Prenons le cas typique. Un utilisateur au lecteur d’écran supprime un produit du panier. La requête AJAX part, le DOM se met à jour, le total change à l’écran. Pour un utilisateur voyant, tout va bien. Pour l’utilisateur au lecteur d’écran, il ne s’est rien passé : rien n’a été annoncé, le focus est éventuellement retombé sur le corps du document, et il n’a aucun moyen de savoir si son action a fonctionné.

Aucun outil automatique ne signalera cela. La page analysée après coup est parfaitement conforme. Le défaut n’existe que dans la transition.

Ce que PrestaShop 9 traite pour vous

Le thème par défaut de PrestaShop 9.1 comporte un dossier dédié à ce sujet précis, avec deux fichiers seulement, ce qui indique bien qu’il s’agit d’un travail ciblé et non d’une couche générale.

src/js/accessibility/cart.ts       68 lignes
src/js/accessibility/product.ts   121 lignes

Le contenu de cart.ts est instructif, parce qu’il décrit exactement le problème ci-dessus et sa réponse :

// hummingbird v2.1.0, src/js/accessibility/cart.ts
// Once PrestaShop finishes updating the cart set aria-live on alerts
// to announce it to screen readers
prestashop.on(events.updatedCart, () => {
  if (state.get('lastUpdateAction') === availableLastUpdateAction.DELETE_FROM_CART) {
    const alertPlaceholder = document.querySelector<HTMLElement>(SelectorsMap.cart.alertPlaceholder);

    if (alertPlaceholder) {
      Array.from(alertPlaceholder.children).forEach((child) => {
        const childElement = child as HTMLElement;

        if (childElement.getAttribute('data-ps-action') === 'to-be-announced') {
          childElement.removeAttribute('data-ps-action');
          childElement.setAttribute('tabindex', '-1');
          childElement.focus();
        }
      });
    } else {
      const cartOverview = document.querySelector<HTMLElement>(SelectorsMap.cart.overview);

      if (cartOverview) {
        a11y.setFocus(cartOverview);
      }
    }
  }

  if (state.get('lastUpdateAction') === availableLastUpdateAction.UPDATE_PRODUCT_QUANTITY) {
    a11y.restoreFocus(/* ... */);
  }
});

Trois choses à en retenir.

La suppression déplace le focus vers l’annonce. Le tabindex="-1" suivi d’un focus() est la technique classique pour rendre un élément focusable par programme sans l’ajouter à l’ordre de tabulation. Sans ça, le message de confirmation existe dans le DOM et n’est jamais lu.

Le changement de quantité restaure le focus. C’est le détail que presque personne n’anticipe : quand le champ de quantité est reconstruit après la requête, l’élément qui avait le focus n’existe plus, et le navigateur remet le focus sur <body>. L’utilisateur au clavier est renvoyé en haut de page au milieu de sa saisie. Il doit alors retraverser toute la page à la tabulation pour revenir à son panier, à chaque modification.

Il existe un repli. Si le conteneur d’alerte est absent, le code se rabat sur la vue d’ensemble du panier. C’est la marque d’un développeur qui a testé sur plusieurs gabarits.

Côté product.ts, le même souci de continuité, appliqué à la galerie d’images :

// hummingbird v2.1.0, src/js/accessibility/product.ts
// Product images sync on open/close modal
document.addEventListener('show.bs.modal', (event) => {
  const modal = event.target as HTMLElement;

  if (!modal.matches(SelectorsMap.product.productImagesModal)) return;

  const modalCarouselElement = modal.querySelector(SelectorsMap.product.productImagesModalCarousel);
  const mainCarouselElement = document.querySelector(SelectorsMap.product.carousel);

  if (!modalCarouselElement || !mainCarouselElement) return;

  const modalCarousel = Carousel.getOrCreateInstance(modalCarouselElement as HTMLElement);
  const activeIndex = getActiveSlideIndex(mainCarouselElement as HTMLElement);

  if (activeIndex !== -1) {
    modalCarousel.to(activeIndex);
  }
});

Sans cette synchronisation, un visiteur qui agrandit la quatrième photo d’un produit se retrouve sur la première, et rien ne le lui dit. C’est le genre de rupture qui passe pour un détail quand on voit l’écran, et qui rend la galerie inutilisable quand on ne le voit pas.

Ce que vos modules vous reprennent

Il faut dire les choses franchement : ce travail du thème ne couvre que le thème. C’est le point que nous avions déjà signalé à propos du choix de thème, et il vaut d’être répété ici.

Sur une boutique réelle, l’essentiel des interactions du tunnel ne vient pas du thème mais des modules, et chacun réinjecte son propre balisage sans rien savoir de ce que le thème a mis en place :

  • La recherche à facettes. Chaque application de filtre est une mise à jour AJAX de la liste de produits. Le nombre de résultats change, souvent sans aucune annonce, et le focus disparaît avec l’ancien bloc de filtres.
  • Les modules de paiement. Beaucoup rendent leur formulaire dans un cadre embarqué dont vous ne maîtrisez ni le balisage, ni l’ordre de tabulation, ni les messages d’erreur. C’est l’endroit le plus critique du parcours et le moins contrôlable.
  • Les fenêtres surgissantes de bandeau cookies, de newsletter ou de vente privée, qui capturent le focus sans le rendre, et dont la croix de fermeture est parfois un <div> non atteignable au clavier.
  • Les blocs de réassurance et carrousels ajoutés par le thème enfant ou par un module, souvent avec des images décoratives portant un alt descriptif inutile, ou l’inverse.

La conclusion pratique est que votre niveau réel d’accessibilité est celui de votre module le moins soigné, pas celui de votre thème. Un audit qui ne teste que les gabarits du thème donne un résultat flatteur et faux.

Les bases, qui restent vraies

Rien de ce qui suit n’a changé, et c’est ce qui règle la majorité des écarts constatés.

Un label lié à son champ, par l’attribut for pointant vers l’id, et les messages d’erreur reliés par aria-describedby :

<label for="email">Adresse e-mail</label>
<input type="email" id="email" name="email" required aria-describedby="email-erreur">
<p id="email-erreur">Veuillez saisir une adresse e-mail valide.</p>

Un focus visible, jamais supprimé. La règle outline: none posée pour des raisons esthétiques est probablement la faute d’accessibilité la plus répandue du web :

:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 2px;
}

Des textes alternatifs qui décrivent, et un alt vide pour le purement décoratif, ce qui n’est pas la même chose qu’un alt absent :

<img src="chaussure.jpg" alt="Chaussure de randonnée en cuir sable, semelle crantée">
<img src="separateur.svg" alt="">

À quoi s’ajoutent un contraste d’au moins 4,5 pour 1 sur le texte courant, une hiérarchie de titres qui ne saute pas de niveau, une information jamais portée par la seule couleur, et des ancres explicites plutôt que des « cliquez ici ».

Le protocole qui attrape ce que les outils ratent

Passez d’abord les outils automatiques, ils sont rapides et ils attrapent les fautes de balisage. Puis faites les deux tests suivants, qui prennent une heure et trouvent ce que les précédents ne peuvent pas voir.

Test 1, sans souris. Débranchez-la, vraiment. Puis passez une commande complète à la tabulation, depuis la page d’accueil jusqu’à la confirmation. Notez chaque fois que vous ne savez plus où vous êtes, chaque fois que le focus disparaît après une action, et chaque fois qu’un élément interactif est inatteignable. Les modifications de quantité dans le panier et le bandeau cookies sont les deux points où l’exercice s’arrête le plus souvent.

Test 2, écran éteint. Avec VoiceOver sur macOS, qui s’active par une combinaison de touches, ou NVDA sur Windows, qui est gratuit. Refaites le même parcours. La question n’est pas « est-ce agréable », elle est « ai-je su, à chaque étape, si mon action avait fonctionné ». Un ajout au panier qui ne produit aucune annonce est un défaut bloquant, même si la page est par ailleurs irréprochable.

Ces deux tests sont à refaire après chaque installation de module qui touche au tunnel, au même titre que les contrôles de mise en ligne. C’est le seul moyen de savoir ce qu’un module vous a repris.

Notre position

L’accessibilité est présentée soit comme une contrainte légale, soit comme un geste d’inclusion. Les deux sont vrais, mais aucun des deux ne dit ce qui se passe concrètement sur une boutique.

Ce qui se passe, c’est qu’une partie de vos visiteurs arrive jusqu’au panier et n’arrive pas à payer, sans que rien dans vos statistiques ne l’explique. Ils ne remplissent pas de formulaire de contact pour le signaler, ils partent. Vous voyez un taux d’abandon, pas une cause.

C’est pour cette raison que nous conseillons de commencer par le tunnel plutôt que par un audit exhaustif du site. C’est là que se trouve l’argent, c’est là que se concentre l’attention des associations et des autorités, et c’est la partie que les outils automatiques couvrent le plus mal.

Questions fréquentes

Suis-je concerné par l’obligation ?
Si vous vendez en ligne à des consommateurs et que vous employez au moins 10 personnes ou réalisez au moins 2 millions d’euros de chiffre d’affaires, oui, depuis le 28 juin 2025. L’exemption microentreprise exige que les deux seuils soient sous la limite.

Dois-je viser le RGAA ou les WCAG ?
La référence de l’EAA est la norme EN 301 549 v3.2.1, qui reprend les WCAG 2.1 niveau AA pour le web. Le RGAA 4.1.2 étant une transposition française de ces mêmes critères, s’en servir comme grille de travail est pertinent, mais le RGAA lui-même s’impose au secteur public, pas aux e-commerçants.

Un bon score Lighthouse suffit-il ?
Non. Les outils automatiques analysent un état figé du document et ne peuvent pas détecter une perte de focus après une requête AJAX, ni une mise à jour qui n’est jamais annoncée. Ce sont pourtant les défauts les plus bloquants sur un tunnel de commande.

Le thème Hummingbird me rend-il conforme ?
Non, il vous met sur une bien meilleure ligne de départ. Il contient du code dédié à l’annonce et à la restauration du focus après les mises à jour du panier, mais il ne peut rien pour le balisage injecté par vos modules, vos textes alternatifs ou vos formulaires de paiement embarqués.

Par où commencer si je n’ai rien fait ?
Par le parcours d’achat testé sans souris, puis avec un lecteur d’écran. Une heure, aucun outil à acheter, et vous saurez si votre boutique est utilisable ou non. Le reste peut attendre ce diagnostic.

Quel est le risque réel ?
Le plafond de sanction est de 250 000 euros en France, mais les premières actions engagées l’ont été par des associations en référé, avec l’exposition publique qui va avec. Le risque juridique n’est plus théorique depuis novembre 2025.

Vous voulez savoir où en est votre tunnel sans lancer un audit complet ? Débranchez votre souris et essayez d’acheter chez vous. Si vous n’y arrivez pas, parlons-en, c’est en général quelques modules qu’il faut reprendre, pas tout le site.

Nous vous recommandons aussi