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

Accessibilité

Advanced Custom Fields et les champs de formulaire sans label programmatique

Un formulaire généré depuis des champs ACF affiche des libellés bien visibles, mais aucun lien réel avec les champs. Le correctif se joue à la génération du gabarit.

Par WordPress Développement • 23 avril 2023 • 5 min de lecture • Aucun commentaire
Advanced Custom Fields et les champs de formulaire sans label programmatique

get_field_object() renvoie un tableau complet avec label, name et value, mais rien ne garantit qu’un développeur restitue ce label sous la forme d’un vrai <label> lié au champ correspondant. C’est précisément le piège rencontré sur un gabarit de formulaire front-end construit à partir d’un groupe de champs Advanced Custom Fields, où chaque champ ressemblait visuellement à un formulaire classique sans en avoir la structure.

Ce texte ne traite pas de la validation des données saisies côté serveur, déjà couverte ailleurs, mais spécifiquement du lien manquant entre libellé affiché et champ de saisie généré dynamiquement à partir d’ACF.

Le symptôme : un formulaire qui a l’air normal

Le gabarit affichait, pour chaque champ du groupe ACF, un paragraphe contenant le libellé en gras suivi d’un champ de saisie sur la ligne suivante :

<?php foreach ( $fields as $field ) : ?>
  <p><strong><?php echo esc_html( $field['label'] ); ?></strong></p>
  <input type="text" name="<?php echo esc_attr( $field['name'] ); ?>">
<?php endforeach; ?>

Visuellement, rien ne choque : le libellé apparaît juste au-dessus du champ, dans le bon ordre de lecture. Mais aucun <label> n’entoure ni ne référence ce texte, et le champ ne possède ni id, ni aria-label, ni aria-labelledby. Un lecteur d’écran annonce simplement « champ de texte », sans aucun contexte.

Pourquoi ACF ne force rien automatiquement

Advanced Custom Fields, côté formulaire d’administration, génère bien ses propres labels correctement associés dans l’écran d’édition. Mais dès qu’un développeur reconstruit un formulaire front-end à partir de get_field_objects() ou d’une boucle sur un groupe de champs, cette association devient entièrement sa responsabilité : ACF fournit les données brutes, pas le markup accessible.

Le cas des champs répétables

Le problème s’aggrave sur un champ répétable (repeater), où le même nom de champ logique se répète plusieurs fois dans le formulaire. Sans identifiant unique généré à chaque itération, plusieurs champs peuvent se retrouver avec le même id, ce qui casse également l’association pour les navigateurs les plus tolérants.

L'essentiel à retenir : Le libellé visible n'est pas toujours un label HTML ; ACF ne force aucune association automatique ; Générer l'id du champ à partir de sa clé ACF

Le correctif : générer un identifiant unique à partir de la clé du champ

La solution consiste à construire un id unique pour chaque champ, généralement à partir de son name ACF combiné à un index de boucle, et à englober réellement le libellé dans un <label> pointant vers cet identifiant :

<?php foreach ( $fields as $index => $field ) :
  $champ_id = 'champ-' . $field['name'] . '-' . $index;
?>
  <label for="<?php echo esc_attr( $champ_id ); ?>">
    <?php echo esc_html( $field['label'] ); ?>
  </label>
  <input type="text" id="<?php echo esc_attr( $champ_id ); ?>"
         name="<?php echo esc_attr( $field['name'] ); ?>">
<?php endforeach; ?>

Pour un champ répétable, ajoutez systématiquement l’index de la ligne courante dans l’identifiant généré, afin qu’aucune collision ne se produise même avec dix ou vingt lignes ajoutées dynamiquement par l’utilisateur.

Le cas des champs sans label visuel

Certains designs se passent volontairement de libellé visible, en s’appuyant sur un texte d’exemple (placeholder) directement dans le champ. Cette pratique reste un anti-pattern : un placeholder disparaît dès la première frappe et n’est pas systématiquement restitué par les technologies d’assistance de la même manière qu’un label. Utilisez alors aria-label comme solution de repli, jamais comme substitut par défaut au vrai label.

  • Toujours un <label> associé par for/id, y compris sur les champs répétables
  • Un identifiant unique par itération de boucle, jamais réutilisé
  • aria-label seulement en dernier recours, sur un champ vraiment sans libellé visuel possible

Vérifier le résultat avec l’inspecteur d’accessibilité du navigateur

Une fois le correctif appliqué, ouvrez l’onglet Accessibilité des DevTools et cliquez sur chaque champ généré : le panneau doit afficher un nom accessible identique au texte du libellé visible. Si le nom accessible reste vide malgré la présence d’un <label>, vérifiez que l’attribut for correspond exactement, caractère pour caractère, à l’id du champ.

Un formulaire ACF qui « a l’air » correctement labellisé à l’écran ne l’est réellement que si le lien for/id existe dans le markup généré, jamais par simple proximité visuelle.

En résumé

ACF fournit les données du champ, jamais leur association accessible : générez systématiquement un identifiant unique par champ, y compris dans une boucle répétable, et reliez-le explicitement à son libellé avec un vrai <label> plutôt qu’un simple paragraphe en gras placé au bon endroit visuellement.

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