Les éléments ne devraient pas avoir un tabindex supérieur à zéro

Un tabindex supérieur à zéro place un élément en tête de l’ordre de tabulation. Les personnes qui utilisent le clavier ou un lecteur d’écran sautent alors d’un endroit à l’autre de la page dans un ordre inattendu, par exemple de l’en-tête directement à un champ d’inscription à la newsletter, et peuvent perdre le chemin du panier ou du paiement.

Identifiant de la règle
tabindex
Source
axe-core 4.13.0
Impact
Grave
Niveau de correction
AUTO
sur Shopify, Shopware, WooCommerce et Magento
Statut
exécutée

Ce que fait le contrôle

Vérifier que les valeurs de l’attribut tabindex ne sont pas supérieures à 0

La règle teste tout élément porteur d’un attribut tabindex, quel que soit l’élément, sauf s’il est masqué aux technologies d’assistance. Elle lit la valeur de l’attribut, pas la propriété DOM. axe-core retire les espaces autour de la valeur et en prend le nombre entier initial, avec un signe facultatif : tabindex="2.5" compte donc comme 2 et tabindex="+1" comme 1. Une valeur qui ne commence pas par un nombre réussit, de même que 0 et les valeurs négatives.

axe-core classe cette règle en bonne pratique, et elle ne correspond à aucun critère de succès des WCAG. Le scanner de Validiscan l’exécute, par défaut, dans une passe de bonne pratique distincte qui ne conserve que les échecs. Le constat est enregistré comme bonne pratique et exclu des tableaux de conformité et du chiffre d’avancement des corrections. Un tabindex positif sur un élément visible qui peut recevoir le focus peut aussi être signalé par vs-focus-order au titre du critère de succès 2.4.3.

La règle ne juge pas si l’ordre de tabulation qui en résulte a un sens, ni si tabindex="0" et tabindex="-1" sont posés sur les bons éléments ; une personne le vérifie au clavier.

Comment corriger

Supprimez les valeurs de tabindex positives ou remplacez-les par tabindex="0", et organisez l’ordre du code source du modèle pour que l’ordre de tabulation naturel suive la mise en page visuelle.

Critères de succès WCAG

Bonne pratique : non rattachée à un critère de succès WCAG.

Où une recette corrige le problème

Shopify : recette remove-positive-tabindex

Afficher l’avant et l’après (1)
Avant et après Données d’exemple

sections/header.liquid Modifications apportées à sections/header.liquid (lignes ajoutées : 1, lignes supprimées : 1)

Modifications apportées à sections/header.liquid (lignes ajoutées : 1, lignes supprimées : 1)
Ligne avant Ligne après Modification Code
37 37
38 38 <div class="header__search">
39 39 <form action="{{ routes.search_url }}" method="get" role="search" class="search">
40 Supprimée <input class="search__input field__input" type="search" name="q" value="" placeholder="{{ 'general.search.placeholder' | t }}" tabindex="1">
40 Ajoutée <input class="search__input field__input" type="search" name="q" value="" placeholder="{{ 'general.search.placeholder' | t }}">
41 41 <button type="submit" class="search__button">
42 42 {%- render 'icon', icon: 'search', size: 20 -%}
43 43 </button>

Shopware : recette remove-positive-tabindex

Afficher l’avant et l’après (1)
removes tabindex="1" from the buy button; vs-focus-order and axe tabindex stop firing Données d’exemple

Resources/views/storefront/page/product-detail/buy-widget.html.twig Modifications apportées à Resources/views/storefront/page/product-detail/buy-widget.html.twig (lignes ajoutées : 1, lignes supprimées : 1)

Modifications apportées à Resources/views/storefront/page/product-detail/buy-widget.html.twig (lignes ajoutées : 1, lignes supprimées : 1)
Ligne avant Ligne après Modification Code
82 82 </div>
83 83 <div class="buy-widget-submit">
84 84 <button class="btn btn-primary btn-buy"
85 Supprimée title="{{ 'detail.addProduct'|trans }}" tabindex="1">
85 Ajoutée title="{{ 'detail.addProduct'|trans }}">
86 86 {{ 'detail.addProduct'|trans }}
87 87 </button>
88 88 </div>

WooCommerce : recette remove-positive-tabindex

Afficher l’avant et l’après (1)
removes tabindex="1" from the header search field of the fixture theme Données d’exemple

header.php Modifications apportées à header.php (lignes ajoutées : 1, lignes supprimées : 1)

Modifications apportées à header.php (lignes ajoutées : 1, lignes supprimées : 1)
Ligne avant Ligne après Modification Code
49 49 <form role="search" method="get" class="woocommerce-product-search" action="<?php echo esc_url( home_url( '/search' ) ); ?>">
50 50 <label class="screen-reader-text" for="woocommerce-product-search-field-0"><?php esc_html_e( 'Search for:', 'woocommerce' ); ?></label>
51 51 <?php // VALIDISCAN-SEED vs-focus-order + tabindex: tabindex="1" "so the search is always the first stop". ?>
52 Supprimée <input type="search" id="woocommerce-product-search-field-0" class="search-field" placeholder="<?php echo esc_attr__( 'Search products&hellip;', 'woocommerce' ); ?>" value="<?php echo get_search_query(); ?>" name="s" tabindex="1">
52 Ajoutée <input type="search" id="woocommerce-product-search-field-0" class="search-field" placeholder="<?php echo esc_attr__( 'Search products&hellip;', 'woocommerce' ); ?>" value="<?php echo get_search_query(); ?>" name="s">
53 53 <?php // VALIDISCAN-SEED button-name: icon-only submit button without text. ?>
54 54 <button type="submit" value="<?php echo esc_attr_x( 'Search', 'submit button', 'woocommerce' ); ?>" class="kb-search-submit"><?php kb_icon( 'search' ); ?></button>
55 55 <input type="hidden" name="post_type" value="product">

Magento : recette remove-positive-tabindex

Afficher l’avant et l’après (1)
removes tabindex 1-4 from the login form and the CAPTCHA and validates Données d’exemple

app/design/frontend/Validiscan/fixture/Magento_Customer/templates/form/captcha-math.phtml Modifications apportées à app/design/frontend/Validiscan/fixture/Magento_Customer/templates/form/captcha-math.phtml (lignes ajoutées : 1, lignes supprimées : 1)

Modifications apportées à app/design/frontend/Validiscan/fixture/Magento_Customer/templates/form/captcha-math.phtml (lignes ajoutées : 1, lignes supprimées : 1)
Ligne avant Ligne après Modification Code
14 14 <div class="field captcha required" role="group" aria-labelledby="captcha-question" data-captcha-type="math">
15 15 <label for="captcha_user_login" class="label" id="captcha-question"><span><?= $escaper->escapeHtml(__('Security question: what is %1 + %2?', $a, $b)) ?></span></label>
16 16 <div class="control captcha">
17 Supprimée <input name="captcha[user_login]" type="text" class="input-text required-entry" id="captcha_user_login" autocomplete="off" inputmode="numeric" tabindex="3" data-captcha-answer-hash="<?= $escaper->escapeHtmlAttr(md5((string) ($a + $b))) ?>">
17 Ajoutée <input name="captcha[user_login]" type="text" class="input-text required-entry" id="captcha_user_login" autocomplete="off" inputmode="numeric" data-captcha-answer-hash="<?= $escaper->escapeHtmlAttr(md5((string) ($a + $b))) ?>">
18 18 </div>
19 19 </div>

app/design/frontend/Validiscan/fixture/Magento_Customer/templates/form/login.phtml Modifications apportées à app/design/frontend/Validiscan/fixture/Magento_Customer/templates/form/login.phtml (lignes ajoutées : 3, lignes supprimées : 3)

Modifications apportées à app/design/frontend/Validiscan/fixture/Magento_Customer/templates/form/login.phtml (lignes ajoutées : 3, lignes supprimées : 3)
Ligne avant Ligne après Modification Code
27 27 <div class="field email required">
28 28 <label class="label" for="email"><span><?= $escaper->escapeHtml(__('Email')) ?></span></label>
29 29 <div class="control">
30 Supprimée <input name="login[username]" value="<?= $escaper->escapeHtmlAttr($username) ?>" autocomplete="off" id="email" type="email" class="input-text mage-error" title="<?= $escaper->escapeHtmlAttr(__('Email')) ?>" aria-invalid="true" tabindex="1" onpaste="return false;" data-mage-init='{"mage/trim-input":{}}'>
30 Ajoutée <input name="login[username]" value="<?= $escaper->escapeHtmlAttr($username) ?>" autocomplete="off" id="email" type="email" class="input-text mage-error" title="<?= $escaper->escapeHtmlAttr(__('Email')) ?>" aria-invalid="true" onpaste="return false;" data-mage-init='{"mage/trim-input":{}}'>
31 31 <div for="email" generated="true" class="mage-error" id="email-error"><?= $escaper->escapeHtml(__('Please enter a valid email address (Ex: johndoe@domain.com).')) ?></div>
32 32 </div>
33 33 </div>
35 35 <div class="field password required">
36 36 <label for="pass" class="label"><span><?= $escaper->escapeHtml(__('Password')) ?></span></label>
37 37 <div class="control">
38 Supprimée <input name="login[password]" type="password" autocomplete="off" class="input-text" id="pass" title="<?= $escaper->escapeHtmlAttr(__('Password')) ?>" tabindex="2" onpaste="return false;" oncopy="return false;">
38 Ajoutée <input name="login[password]" type="password" autocomplete="off" class="input-text" id="pass" title="<?= $escaper->escapeHtmlAttr(__('Password')) ?>" onpaste="return false;" oncopy="return false;">
39 39 </div>
40 40 </div>
41 41 <!-- VALIDISCAN-SEEDED vs-accessible-auth: arithmetic CAPTCHA with no alternative -->
42 42 <?= $block->getChildHtml('form_additional_info') /* math CAPTCHA module: div.field.captcha, input#captcha_user_login tabindex="3" */ ?>
43 43 <div class="actions-toolbar">
44 Supprimée <div class="primary"><button type="submit" class="action login primary" name="send" id="send2" tabindex="4"><span><?= $escaper->escapeHtml(__('Sign In')) ?></span></button></div>
44 Ajoutée <div class="primary"><button type="submit" class="action login primary" name="send" id="send2"><span><?= $escaper->escapeHtml(__('Sign In')) ?></span></button></div>
45 45 <div class="secondary"><a class="action remind" href="<?= $escaper->escapeUrl($block->getUrl('contact')) ?>"><span><?= $escaper->escapeHtml(__('Forgot Your Password? Contact us')) ?></span></a></div>
46 46 </div>
47 47 </fieldset>

Commencez par une vérification gratuite de votre boutique.

Envoyez l’adresse de votre boutique. Validiscan la scanne et vous envoie chaque échec que le scan peut prouver, avec sa page et son code.

Demander une vérification gratuite

Ou écrivez à info@validiscan.com.

Ce que couvre la vérification gratuite, et ce qu’elle laisse de côté
Vous envoyez
l’adresse de votre boutique
Pages scannées
jusqu’à 15
Vous recevez
chaque échec que le scan peut prouver, avec la page et le code
Sur votre boutique
pages publiques uniquement ; aucune connexion, aucun achat, aucun formulaire envoyé
Ce qu’elle n’est pas
un audit complet

Écrire à Validiscan

Pour une vérification gratuite, indiquez l’adresse de votre boutique et sa plateforme.

Validiscan utilise ce que vous envoyez pour vous répondre. Politique de confidentialité