Un en-tête collant qui reste visible pendant le défilement est un choix de confort courant sur les thèmes WordPress récents. Le problème apparaît quand on navigue au clavier dans un menu long ou une page riche en liens : à un moment donné, l’élément qui reçoit le focus se retrouve physiquement sous l’en-tête collant, complètement invisible, alors même que le focus logique a bien avancé. La personne qui navigue au clavier continue d’appuyer sur Tab sans jamais voir où elle en est.
C’est exactement ce que couvre le critère 2.4.11 « Focus non masqué (a minima) » de WCAG 2.2, de niveau AA : quand un composant reçoit le focus clavier, il ne doit pas être entièrement caché par un autre contenu créé par l’auteur du site (en-tête collant, bandeau de cookies, barre d’annonce fixe). Ce billet montre comment le mettre en œuvre sur un thème WordPress classique, sans toucher au comportement du défilement de page lui-même, qui reste hors sujet ici.
Étape 1 : reproduire le problème pour le mesurer
Avant de corriger, il faut voir le défaut. Sur une page avec un en-tête collant d’environ 80 pixels de hauteur, on navigue au clavier avec Tab jusqu’à un lien situé juste après le début du contenu principal. Sur la majorité des thèmes non corrigés, ce lien apparaît partiellement ou totalement sous l’en-tête au moment où il reçoit le focus, car le navigateur scrolle juste assez pour amener l’élément en haut de la zone visible, sans tenir compte de la hauteur de l’en-tête collant qui se superpose par-dessus.
Étape 2 : réserver de l’espace avec scroll-margin-top
La solution la plus simple, et suffisante dans la majorité des cas, ne demande aucun JavaScript : la propriété CSS scroll-margin-top, appliquée aux éléments focalisables, indique au navigateur de laisser une marge lors du défilement automatique qui accompagne le focus.

:root {
--hauteur-en-tete: 80px;
}
a, button, input, select, textarea, [tabindex] {
scroll-margin-top: calc(var(--hauteur-en-tete) + 16px);
}
La variable CSS --hauteur-en-tete doit refléter la hauteur réelle de l’en-tête collant, y compris ses éventuelles marges. Sur un thème utilisant theme.json, il est possible de synchroniser cette valeur avec la variable qui définit déjà la hauteur de l’en-tête dans les styles globaux, pour éviter les décalages en cas de mise à jour.
Étape 3 : traiter les cas que scroll-margin-top ne couvre pas
Cette propriété fonctionne bien pour le focus obtenu par déplacement du curseur de lecture du navigateur, mais elle ne s’applique pas automatiquement quand le focus est déplacé par du JavaScript (par exemple l’ouverture d’une modale qui place le focus sur son premier champ). Dans ce cas, il faut vérifier explicitement, après chaque appel à .focus() déclenché par script, que l’élément ciblé n’est pas recouvert :
function focusVisible(element) {
element.focus();
const rect = element.getBoundingClientRect();
const hauteurEnTete = document
.querySelector('.site-header')
.getBoundingClientRect().height;
if (rect.top < hauteurEnTete) {
window.scrollBy(0, rect.top - hauteurEnTete - 16);
}
}
Étape 4 : ne pas oublier les bandeaux temporaires
L’en-tête collant n’est pas le seul coupable. Un bandeau de consentement aux cookies fixé en bas d’écran, ou une barre d’annonce promotionnelle collée en haut, produisent exactement le même défaut s’ils restent affichés pendant la navigation au clavier. La checklist de vérification doit donc inclure tout élément positionné en position: fixed ou position: sticky, pas seulement l’en-tête principal du thème.
- En-tête de navigation collant.
- Bandeau de consentement aux cookies, s’il reste affiché après acceptation partielle.
- Barre d’annonce ou de promotion fixée en haut ou en bas.
- Bouton de retour en haut de page, s’il est suffisamment grand pour recouvrir un élément focalisé.
Étape 5 : valider avec un test clavier de bout en bout
La vérification finale consiste à parcourir la page entière à coups de Tab, en s’assurant qu’à chaque étape l’élément qui a le focus reste au moins partiellement visible, en dehors de la zone couverte par l’en-tête collant ou tout autre élément fixe. Un contrôle automatisé peut compléter ce test manuel en calculant, pour chaque élément focalisable, si son rectangle de position chevauche celui des éléments fixes de la page.
En résumé
Le critère 2.4.11 se corrige, dans la grande majorité des cas WordPress, avec une seule propriété CSS bien calibrée : scroll-margin-top. Les cas gérés par script demandent une vérification explicite après chaque déplacement de focus programmatique. Le point à ne pas négliger reste l’inventaire complet des éléments fixes de la page — en-tête, bandeau cookies, barre d’annonce — car c’est souvent l’élément qu’on oublie qui fait échouer l’audit.