Interactive targets must be at least 24 by 24 CSS pixels

Tiny quantity buttons, close icons, colour swatches and filter checkboxes are hard to hit for people with tremors or limited dexterity, and for anyone on a phone. They tap the wrong size, remove the wrong item or give up, which costs orders on mobile in particular.

Rule id
vs-target-size
Source
Validiscan check
Impact
Serious
Fix tier
AUTO
on Shopify, Shopware, WooCommerce and Magento
Status
runs

What the check does

Measures links, buttons and form controls and flags targets smaller than 24x24 CSS pixels that do not meet the spacing exception (2.5.8). Links inside running text are excluded. Supersedes the axe rule target-size.

The check also measures summary elements and elements with roles such as checkbox, tab and option, so listbox color swatches count. Disabled, hidden and zero-size targets are skipped, as are skip links parked off the page. A control’s visible <label> adds to its measured box.

A target is small when its width or height is below 24 CSS px, with 0.25 px allowed for sub-pixel layout. A small target still passes when:

  • a 24 px circle centered on it reaches neither another target’s box nor the circle of another small target outside running text;
  • it is an inline element, or an inline-block link, in a block that also holds text outside any target. A heading above a list of links does not count.

The check runs separately in each scanned viewport, by default desktop (1440 px) and mobile (390 px), so a target that shrinks only on phones is reported for mobile. It does not apply the equivalent, user agent control or essential exceptions; a person judges those.

How to fix it

Give icon buttons and small controls a hit area of at least 24x24 CSS pixels (44x44 is better on touch screens), for example with padding or min-width and min-height, without changing the visible icon. Where a target must stay small, keep at least 24 pixels between it and its neighbours.

WCAG success criteria

EN 301 549 clauses

The EN 301 549 clause of each criterion, by version of the standard
WCAG criterion Version 3.2.1 Version 4.1.1
2.5.8 not a clause in this version 9.2.5.8

Where a recipe fixes it

Shopify: recipe target-size-padding

Show the before and after (1)
Before and after Example data

assets/base.css.liquid Changes to assets/base.css.liquid: 10 added, 0 removed

Changes to assets/base.css.liquid: 10 added, 0 removed
Line before Line after Change Code
1866 1866 }
1867 1867
1868 1868 /* ----------------------------------------------------------------- motion */
1869 Added
1870 Added /* validiscan:target-size-padding */
1871 Added .header__icon--account,
1872 Added .header__icon--cart,
1873 Added .swatch--button,
1874 Added .quantity__button {
1875 Added min-width: 24px;
1876 Added min-height: 24px;
1877 Added }
1878 Added /* /validiscan:target-size-padding */

Shopware: recipe target-size-padding

Show the before and after (1)
gives the header icons, steppers and swatches a 24px minimum; no page reports small targets Example data

Resources/app/storefront/src/scss/_variant-broken.scss Changes to Resources/app/storefront/src/scss/_variant-broken.scss: 6 added, 2 removed

Changes to Resources/app/storefront/src/scss/_variant-broken.scss: 6 added, 2 removed
Line before Line after Change Code
10 10
11 11 .header-actions-btn {
12 12 width: 18px;
13 Added min-width: 24px;
13 14 height: 18px;
14 Removed min-height: 0;
15 Added min-height: 24px;
15 16 padding: 0;
16 17 }
17 18
96 97 /* 18 px colour swatches, 20 px quantity and remove buttons (vs-target-size). */
97 98 .product-detail-configurator-option-input {
98 99 width: 18px;
100 Added min-width: 24px;
99 101 height: 18px;
102 Added min-height: 24px;
100 103 margin-right: 4px;
101 104 }
102 105
103 106 .quantity-selector-group .btn,
104 107 .line-item-remove-button {
105 108 width: 20px;
109 Added min-width: 24px;
106 110 height: 20px;
107 Removed min-height: 0;
111 Added min-height: 24px;
108 112 padding: 0;
109 113 }
110 114

WooCommerce: recipe target-size-padding

Show the before and after (1)
raises the social icons, quantity steppers and swatches of the fixture theme to 24 × 24 px Example data

assets/css/main.css Changes to assets/css/main.css: 4 added, 2 removed

Changes to assets/css/main.css: 4 added, 2 removed
Line before Line after Change Code
710 710 /* VALIDISCAN-SEED vs-target-size: 18 x 18 px icon links, 4 px apart. */
711 711 .kb-social__link {
712 712 display: inline-flex;
713 Removed width: 18px;
714 Removed height: 18px;
713 Added width: 24px;
714 Added height: 24px;
715 715 color: var(--kb-ink);
716 Added align-items: center;
717 Added justify-content: center;
716 718 }
717 719
718 720 .site-info {

assets/css/woocommerce.css Changes to assets/css/woocommerce.css: 4 added, 4 removed

Changes to assets/css/woocommerce.css: 4 added, 4 removed
Line before Line after Change Code
421 421
422 422 /* VALIDISCAN-SEED vs-target-size: 18 x 18 px colour swatches, 4 px apart. */
423 423 .kb-swatch {
424 Removed width: 18px;
425 Removed height: 18px;
424 Added width: 24px;
425 Added height: 24px;
426 426 padding: 0;
427 427 border: 1px solid rgba(0, 0, 0, 0.2);
428 428 border-radius: 50%;
489 489 /* VALIDISCAN-SEED vs-target-size: 18 x 18 px quantity steppers glued to the input. */
490 490 .kb-qty-minus,
491 491 .kb-qty-plus {
492 Removed width: 18px;
493 Removed height: 18px;
492 Added width: 24px;
493 Added height: 24px;
494 494 padding: 0;
495 495 border: 1px solid #b9b3aa;
496 496 border-radius: 2px;

Magento: recipe target-size-padding

Show the before and after (1)
sizes the three flagged controls and validates Example data

app/design/frontend/Validiscan/fixture/web/css/source/_theme.less Changes to app/design/frontend/Validiscan/fixture/web/css/source/_theme.less: 9 added, 0 removed

Changes to app/design/frontend/Validiscan/fixture/web/css/source/_theme.less: 9 added, 0 removed
Line before Line after Change Code
1264 1264 height: 18px;
1265 1265 stroke-width: 3;
1266 1266 }
1267 Added
1268 Added /* validiscan:target-size-padding */
1269 Added .social-link,
1270 Added .actions-secondary .action,
1271 Added .qty-step {
1272 Added min-width: 24px;
1273 Added min-height: 24px;
1274 Added }
1275 Added /* /validiscan:target-size-padding */

app/design/frontend/Validiscan/fixture/web/css/styles-m.css Changes to app/design/frontend/Validiscan/fixture/web/css/styles-m.css: 9 added, 0 removed

Changes to app/design/frontend/Validiscan/fixture/web/css/styles-m.css: 9 added, 0 removed
Line before Line after Change Code
1232 1232 height: 18px;
1233 1233 stroke-width: 3;
1234 1234 }
1235 Added
1236 Added /* validiscan:target-size-padding */
1237 Added .social-link,
1238 Added .actions-secondary .action,
1239 Added .qty-step {
1240 Added min-width: 24px;
1241 Added min-height: 24px;
1242 Added }
1243 Added /* /validiscan:target-size-padding */

Start with a free check of your shop.

Send your shop’s address. Validiscan scans it and replies with every failure the scan can prove, with the page and the code.

Request a free check

Or write to info@validiscan.com.

What the free check covers, and what it leaves out
You send
your shop’s address
Pages scanned
up to 15
You get
every failure the scan can prove, with the page and the code
On your shop
public pages only; no login, nothing bought, no forms sent
What it is not
a full audit

Write to Validiscan

For a free check, give the address of your shop and its platform.

Validiscan uses what you send to answer you. Privacy notice