WCAG A Prestataire Complexe

Les contenus cachés de votre site — panneaux repliés, menus fermés, éléments hors écran — sont-ils invisibles aux logiciels de lecture quand ils ne sont pas affichés ?

Critère officiel 10.8 — Pour chaque page web, les contenus cachés ont-ils vocation à être ignorés par les technologies d’assistance ?

Pourquoi c'est important

Un logiciel de lecture peut annoncer du contenu visuellement caché si ce dernier n'est pas correctement masqué aux technologies d'assistance. À l'inverse, du contenu utile peut être ignoré alors qu'il devrait être accessible après une action. Dans les deux cas, l'utilisateur reçoit une information fausse sur ce que contient la page.

Exemples concrets

Ce qui est conforme

L'accordéon FAQ fonctionne correctement : quand une section est fermée, son contenu est masqué aux logiciels de lecture. Quand elle s'ouvre, le contenu devient accessible. L'état annoncé correspond toujours à ce qui est réellement affiché.

Ce qui pose problème

Le menu de navigation mobile est caché visuellement sur ordinateur, mais son contenu reste lu par les logiciels de lecture. L'utilisateur entend les 15 liens du menu mobile avant même d'atteindre le contenu de la page — alors que ce menu n'est pas du tout utilisable sur l'écran actuel.

Comment agir

Ce critère est entièrement technique. Demandez à votre prestataire de vérifier que tous les contenus masqués (via CSS ou JavaScript) sont correctement déclarés comme invisibles aux technologies d'assistance, et que les contenus accessibles après une action (accordéons, onglets) sont bien annoncés à l'ouverture. Question à poser : « Nos contenus dynamiquement affichés ou masqués utilisent-ils les attributs ARIA d'état correctement ? »

Règles clés

  • Contenu à masquer AUSSI aux AT : display:none, visibility:hidden, ou attribut hidden. Pour les composants dynamiques : aria-hidden='true' si l'élément doit rester dans le DOM.
  • Contenu à masquer UNIQUEMENT visuellement (garder accessible aux AT) : technique clip masking via position:absolute + clip + overflow:hidden — jamais display:none ni visibility:hidden.
  • Un panneau d'accordéon fermé doit être masqué aux AT : utiliser hidden sur le panneau ou display:none via JS.
  • Un skip link doit être focusable au clavier : clip masking, jamais display:none.
  • aria-hidden='true' ne retire pas l'élément du flux de tabulation — combiner avec tabindex='-1' si nécessaire.

Erreurs fréquentes

  • Panneau d'accordéon masqué via opacity:0 ou visibility:hidden — masqué visuellement mais toujours lu par les AT
  • Slide de carrousel inactive masquée via left:-9999px ou transform:translateX — accessible aux AT alors qu'elle n'est pas visible
  • Skip link masqué avec display:none — inaccessible au clavier ET aux AT
  • Modal fermée sans hidden ni aria-hidden='true' — son contenu reste dans l'arbre d'accessibilité
  • Technique sr-only implémentée incorrectement (clip:auto ou overflow:visible) — visible aux AT mais hors viewport

Exemples de code

panneau masqué visuellement mais lisible par les AT

✗ Non conforme
/* Panneau d'accordéon 'fermé' */
.panel-ferme {
  visibility: hidden;
  height: 0;
  overflow: hidden;
  /* visibility:hidden masque visuellement
     mais le contenu reste dans l'arbre AT */
}

visibility:hidden masque l'élément à l'écran mais ne le retire pas de l'arbre d'accessibilité. Le lecteur d'écran peut encore atteindre les liens et boutons dans ce panneau via la tabulation.

panneau correctement masqué aux AT

✓ Conforme
<!-- HTML : attribut hidden sur le panneau fermé -->
<div id="panneau-1" hidden>
  <p>Contenu du panneau...</p>
</div>

<!-- Script : retirer hidden à l'ouverture -->
<script>
btnAccordeon.addEventListener('click', () => {
  const estOuvert = panneau.hasAttribute('hidden');
  if (estOuvert) {
    panneau.removeAttribute('hidden');
    btn.setAttribute('aria-expanded', 'true');
  } else {
    panneau.setAttribute('hidden', '');
    btn.setAttribute('aria-expanded', 'false');
  }
});
</script>

L'attribut HTML hidden masque l'élément visuellement ET le retire de l'arbre d'accessibilité. Simple et robuste. À la fermeture, le contenu est inaccessible au clavier et aux AT.

skip link masqué avec display:none

✗ Non conforme
.skip-link {
  display: none; /* ERREUR : inaccessible au clavier */
}
.skip-link:focus {
  display: block;
}

display:none retire l'élément de l'ordre de tabulation. Le skip link ne peut jamais recevoir le focus — il est donc inutile. Le :focus ne sera jamais déclenché.

skip link masqué avec clip masking

✓ Conforme
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* Visible au focus clavier */
.sr-only:focus,
.sr-only:focus-within {
  position: static;
  width: auto;
  height: auto;
  padding: 0.5rem 1rem;
  margin: 0;
  overflow: visible;
  clip: auto;
  white-space: normal;
  /* Styles visuels du lien visible */
  background: #1a1a6e;
  color: white;
  font-weight: bold;
  z-index: 9999;
}

Le clip masking maintient l'élément dans le flux de tabulation et dans l'arbre AT. Au focus clavier, les styles :focus le rendent visible. C'est la technique correcte pour les skip links et labels complémentaires.

modal fermée sans masquage AT

✗ Non conforme
/* Modal 'fermée' via CSS uniquement */
.modal {
  opacity: 0;
  pointer-events: none;
  transform: scale(0.95);
  /* Toujours dans l'arbre AT — ses boutons
     sont encore focusables */
}

La modal est invisible visuellement mais ses éléments interactifs (boutons, liens) restent dans l'ordre de tabulation et dans l'arbre AT. L'utilisateur clavier tombe dessus sans le savoir.

modal fermée correctement

✓ Conforme
<!-- Modal fermée : attribut hidden -->
<div role="dialog" aria-modal="true"
  aria-labelledby="modal-titre"
  id="ma-modal"
  hidden>
  <h2 id="modal-titre">Confirmation</h2>
  <button type="button" id="btn-fermer"
    aria-label="Fermer la fenêtre">×</button>
  <p>Êtes-vous sûr ?</p>
  <button type="button">Confirmer</button>
</div>

L'attribut hidden retire la modal de l'arbre AT et de l'ordre de tabulation. À l'ouverture, le script retire hidden et place le focus sur le premier élément focusable.

Référence WCAG : 1.3.2, 4.1.2

La lettre de l'Atelier A11Y

Ressources pédagogiques, critères RGAA commentés et retours de terrain : une lettre mensuelle pour progresser sur l'accessibilité numérique, sans jargon.

  • Nouveaux articles et ressources pédagogiques
  • Critères RGAA décortiqués avec des exemples concrets
  • Bonnes pratiques et retours d'expérience terrain
S'abonner à la newsletter (s'ouvre dans un nouvel onglet)

Gratuit. Désabonnement possible à tout moment.