Le WordPress d'aujourd'hui, décodé pour les développeurs

Accessibilité

Elementor et une extension d’accessibilité : les conflits de focus partagés

Deux scripts qui gèrent le focus clavier sur le même composant Elementor finissent par se marcher dessus. Voici comment repérer lequel doit gagner.

Par WordPress Développement • 1 février 2022 • 5 min de lecture • Aucun commentaire
Elementor et une extension d'accessibilité : les conflits de focus partagés

Un accordéon Elementor qui s’ouvre au clic mais dont le focus atterrit tantôt sur le bon panneau, tantôt trois éléments plus loin : c’est le genre de bug qui rend fou parce qu’il n’est pas reproductible à chaque tentative. Sur un projet récent pour un client du secteur de la formation professionnelle, ce comportement erratique n’apparaissait qu’avec NVDA activé, jamais en navigation clavier seule sans lecteur d’écran.

La cause, une fois isolée, était presque banale : une extension d’accessibilité premium installée en parallèle du thème gérait elle aussi le focus des accordéons et des onglets Elementor, avec sa propre logique de tabindex dynamique. Deux scripts, deux logiques, un seul DOM : le second à s’exécuter écrasait silencieusement le travail du premier.

Le symptôme observé

Le rapport initial du client tenait en une phrase : « le focus part n’importe où après avoir ouvert une question de la FAQ ». En creusant avec le clavier seul, rien d’anormal n’apparaissait : Tab suivait un ordre logique, Entrée ouvrait le bon panneau, le focus restait sur l’en-tête cliqué. Le problème ne se manifestait qu’en combinant clavier et lecteur d’écran, ou après plusieurs ouvertures/fermetures successives du même accordéon.

Un test plus systématique a montré que le focus finissait parfois sur le panneau suivant, parfois sur un bouton « voir plus » situé hors de l’accordéon, parfois nulle part de perceptible pour l’utilisateur de lecteur d’écran alors que le focus DOM avait bien bougé. Ce genre de symptôme intermittent est la signature typique d’une course entre deux gestionnaires d’événements sur la même cible.

Diagnostic : deux scripts, une seule cible

L'essentiel à retenir : Deux gestionnaires de focus actifs sur le même composant créent des sauts imprévisibles ; L'ordre de chargement des scripts détermine souvent, à tort, la priorité ; Un seul script doit posséder la gestion du focus par composant

L’inspection du panneau « Sources » des outils de développement a permis de lister les scripts injectés sur la page : le script natif d’Elementor pour les accordéons (widget-scripts.js), et un script de l’extension d’accessibilité qui reformattait la structure ARIA de tous les éléments role="tablist" et role="accordion" détectés au chargement.

Les deux scripts posaient un écouteur click sur le même en-tête d’accordéon. Celui d’Elementor gérait l’ouverture visuelle et déplaçait le focus vers le contenu ouvert. Celui de l’extension, exécuté juste après, réappliquait sa propre logique de focus basée sur un cache DOM construit au chargement initial de la page — cache qui ne tenait pas compte des accordéons déjà ouverts, d’où les sauts imprévisibles après plusieurs interactions.

  • Repérer tous les scripts qui posent un écouteur sur les mêmes sélecteurs CSS (.elementor-accordion-item, [role="tab"]…)
  • Vérifier l’ordre de chargement dans l’onglet Réseau : le dernier script exécuté gagne généralement la course
  • Désactiver temporairement l’extension d’accessibilité pour confirmer que le bug disparaît
  • Chercher dans la documentation de l’extension une option d’exclusion par sélecteur ou par widget

Le correctif retenu

La bonne pratique n’est pas de choisir le script « le plus récent » ou « le plus configurable », mais celui qui reste synchronisé avec l’état réel du DOM après chaque interaction. Ici, le script natif d’Elementor recalculait l’état à chaque clic ; celui de l’extension travaillait sur un instantané figé au chargement. Le choix s’est donc porté sur le script Elementor pour la gestion du focus, en désactivant ce comportement précis dans l’extension via son panneau de configuration, qui proposait heureusement une case « Désactiver la gestion du focus sur les accordéons ».

Quand une telle option n’existe pas, une solution de repli consiste à retirer l’écouteur concurrent avec removeEventListener une fois la page chargée, en ciblant précisément le composant concerné plutôt que l’extension entière — pour ne pas perdre les autres apports utiles de celle-ci, comme l’ajout de aria-live sur les zones de notification.

document.querySelectorAll('.elementor-accordion-item .elementor-tab-title').forEach(function (header) {
  const clone = header.cloneNode(true);
  header.parentNode.replaceChild(clone, header);
});
// Le clone perd les écouteurs de l'extension tierce
// Elementor réattache ensuite son propre écouteur au prochain rendu

Prévenir la récidive sur les futurs projets

Sur les projets suivants pour ce même client, la règle est devenue simple : avant d’ajouter une extension d’accessibilité en plus des composants natifs du page builder, un test manuel systématique porte sur les composants interactifs qui gèrent déjà eux-mêmes leur focus — accordéons, onglets, carrousels, modales. Si l’extension propose une fonctionnalité qui recoupe l’existant, elle est désactivée pour ce composant précis plutôt que désinstallée entièrement.

Un audit rapide au clavier après chaque mise à jour majeure d’Elementor ou de l’extension fait désormais partie de la checklist de recette, car ce type de conflit réapparaît régulièrement après une montée de version qui modifie subtilement l’ordre de chargement des scripts.

En résumé

Deux scripts qui gèrent le focus du même composant ne coexistent jamais bien longtemps sans accroc. Le diagnostic passe par l’identification précise des écouteurs concurrents, et le correctif par le choix du script qui reste synchronisé avec l’état réel de l’interface — pas nécessairement celui installé en dernier. Sur ce projet, ce contrôle de focus repris à l’extension a permis de retrouver un comportement stable et prévisible, validé ensuite avec NVDA et VoiceOver.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Partager :

À propos de l'auteur

WordPress Développement

Développeur WordPress, passionné par Elementor, le FSE et l’automatisation par IA.

Voir tous ses articles

Dans la même veine

À lire aussi