Elementer bør ikke have et tabindex større end nul
Et tabindex større end nul tvinger et element frem forrest i tastaturrækkefølgen. Tastatur- og skærmlæserbrugere hopper så rundt på siden i en uventet rækkefølge, for eksempel fra headeren direkte til et felt til nyhedsbrevet, og kan fare vild på vejen til kurven eller kassen.
- Regel-id
- tabindex
- Kilde
- axe-core 4.13.0
- Alvorlighed
- Alvorlig
- Rettelsesniveau
- AUTO
- på Shopify, Shopware, WooCommerce og Magento
- Status
- køres
Hvad kontrollen gør
Sørg for, at tabindex-værdier ikke er større end 0
Reglen tester hvert element med en tabindex-attribut, uanset elementtype, medmindre det er skjult for hjælpemidler. Den læser attributtens værdi, ikke DOM-egenskaben. axe-core fjerner blanktegn omkring værdien og tager det indledende hele tal med et eventuelt fortegn, så tabindex="2.5" tæller som 2 og tabindex="+1" som 1. En værdi uden et indledende tal består, og det gør 0 og negative værdier også.
axe-core mærker reglen som god praksis, og den er ikke knyttet til noget WCAG-succeskriterium. Validiscans scanner kører den som standard i et særskilt gennemløb for god praksis, der kun beholder fejlene. Fundet gemmes som god praksis og holdes ude af overensstemmelsestabellerne og tallet for fremskridt i udbedringen. En positiv tabindex på et synligt element, der kan få fokus, kan også blive rapporteret af vs-focus-order under succeskriterium 2.4.3.
Reglen vurderer ikke, om den tab-rækkefølge, der opstår, giver mening, eller om tabindex="0" og tabindex="-1" sidder på de rigtige elementer; det tjekker et menneske med tastaturet.
Sådan retter du det
Fjern positive tabindex-værdier, eller lav dem om til tabindex="0", og tilpas rækkefølgen i skabelonens kildekode, så den naturlige tab-rækkefølge følger det visuelle layout.
WCAG-succeskriterier
God praksis: ikke knyttet til et succeskriterium i WCAG.
Hvor en opskrift retter det
Shopify: opskrift remove-positive-tabindex
Vis før og efter (1)
sections/header.liquid Ændringer i sections/header.liquid: 1 tilføjet, 1 fjernet
| Linje før | Linje efter | Ændring | Kode |
|---|---|---|---|
| 37 | 37 | ||
| 38 | 38 | <div class="header__search"> | |
| 39 | 39 | <form action="{{ routes.search_url }}" method="get" role="search" class="search"> | |
| 40 | Fjernet | <input class="search__input field__input" type="search" name="q" value="" placeholder="{{ 'general.search.placeholder' | t }}" tabindex="1"> | |
| 40 | Tilføjet | <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: opskrift remove-positive-tabindex
Vis før og efter (1)
Resources/views/storefront/page/product-detail/buy-widget.html.twig Ændringer i Resources/views/storefront/page/product-detail/buy-widget.html.twig: 1 tilføjet, 1 fjernet
| Linje før | Linje efter | Ændring | Kode |
|---|---|---|---|
| 82 | 82 | </div> | |
| 83 | 83 | <div class="buy-widget-submit"> | |
| 84 | 84 | <button class="btn btn-primary btn-buy" | |
| 85 | Fjernet | title="{{ 'detail.addProduct'|trans }}" tabindex="1"> | |
| 85 | Tilføjet | title="{{ 'detail.addProduct'|trans }}"> | |
| 86 | 86 | {{ 'detail.addProduct'|trans }} | |
| 87 | 87 | </button> | |
| 88 | 88 | </div> |
WooCommerce: opskrift remove-positive-tabindex
Vis før og efter (1)
header.php Ændringer i header.php: 1 tilføjet, 1 fjernet
| Linje før | Linje efter | Ændring | Kode |
|---|---|---|---|
| 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 | Fjernet | <input type="search" id="woocommerce-product-search-field-0" class="search-field" placeholder="<?php echo esc_attr__( 'Search products…', 'woocommerce' ); ?>" value="<?php echo get_search_query(); ?>" name="s" tabindex="1"> | |
| 52 | Tilføjet | <input type="search" id="woocommerce-product-search-field-0" class="search-field" placeholder="<?php echo esc_attr__( 'Search products…', '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: opskrift remove-positive-tabindex
Vis før og efter (1)
app/design/frontend/Validiscan/fixture/Magento_Customer/templates/form/captcha-math.phtml Ændringer i app/design/frontend/Validiscan/fixture/Magento_Customer/templates/form/captcha-math.phtml: 1 tilføjet, 1 fjernet
| Linje før | Linje efter | Ændring | Kode |
|---|---|---|---|
| 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 | Fjernet | <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 | Tilføjet | <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 Ændringer i app/design/frontend/Validiscan/fixture/Magento_Customer/templates/form/login.phtml: 3 tilføjet, 3 fjernet
| Linje før | Linje efter | Ændring | Kode |
|---|---|---|---|
| 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 | Fjernet | <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 | Tilføjet | <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 | Fjernet | <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 | Tilføjet | <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 | Fjernet | <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 | Tilføjet | <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> |
Begynd med et gratis tjek af din webshop.
Send din webshops adresse. Validiscan scanner den og svarer med hver fejl, scanningen kan påvise, med siden og koden.
Bestil et gratis tjekEller skriv til info@validiscan.com.
Hvad det gratis tjek omfatter, og hvad det udelader- Du sender
- din webshops adresse
- Sider, der scannes
- op til 15
- Du får
- hver fejl, scanningen kan påvise, med siden og koden
- På din webshop
- kun offentlige sider; intet login, intet købt, ingen formularer sendt
- Hvad det ikke er
- et fuldt audit