Direct answer: all 25 homepages rendered at 390x844. Of 852 matched controls, 427 are non-inline targets, and 156 (36.5%) are under 24px in at least one dimension: 114 non-carousel controls and 42 carousel dots. Twenty sites have at least one, 22 small targets have no accessible name, After the 24px spacing exception, 78 pass and 78 still fail (39 non-carousel controls and 39 dots), with failures on 10 sites. Four pages scroll sideways: E30 +810px, E28 +732, E06 +220 and E11 +14.
The 24px floor comes from WCAG 2.2 success criterion 2.5.8 (AA); 44x44 is Apple's HIG recommendation and 48x48 is Material's. This run measures the boxes and then applies the 24px spacing exception: of 156, 78 pass and 78 still fail.
Method: render each site at 390x844, then measure boxes
On 2026-11-09 between 16:45 and 16:49 we opened the same 25 equipment homepages one tab at a time with headless Chrome 124 and the DevTools Protocol: a 390x844 viewport at DPR 1 with a desktop user agent, waiting 2.5 seconds after readyState reached complete before reading each control's getBoundingClientRect(). No scrolling, clicking, logging in or form submission. All 25 sites rendered.
| Rule | Definition | Boundary |
|---|---|---|
| Control | a[href], button, input[type=submit|button], [role=button] | No select, textarea or label |
| Non-inline target | Link or button whose computed display is not inline | 425 inline text links are listed separately and excluded |
| Under 24 | Width or height below 24 CSS px | WCAG 2.2 2.5.8 AA minimum |
| Under 44 | Width or height below 44 CSS px | Apple 44 and Material 48 reference |
| Carousel dot | Class contains swiper-pagination, slick-dots, owl-dots, carousel-indicators or pagination | Still a control, listed separately |
| Unnamed | No aria-label, title, img alt, visible text or value | Presence only, not name quality |
| Sideways overflow | documentElement.scrollWidth minus 390 | Above zero means the page can be dragged sideways; fixed elements are excluded from contributors |
Results: 20 sites have a control under 24px
The 156 sub-24 targets are 36.5% of non-inline targets; removing carousel dots still leaves 114 on 18 sites. At the 44px reference, 24 sites have at least one target below it, 292 in total. More controls do not mean more problems: E24 has 77 targets but only 3 under 24px; E06 has 39 targets, 18 of them dots, and zero non-carousel controls under 24.
| Measure | Result | Note |
|---|---|---|
| Renderable homepages | 25/25 | All rendered this run |
| Matched controls | 852 | Includes inline links |
| Non-inline targets | 427 | Denominator |
| Inline text links | 425 | WCAG exemption, excluded |
| Under 24px | 156 (36.5%) | Either dimension |
| Non-carousel controls | 114 | 18 sites |
| Carousel dots | 42 | 6 sites |
| Under 44px | 292 | 24 sites |
| Non-carousel under 44 | 250 | Reference only |
| Unnamed small targets | 22 | 6 sites |
| Sites with a sub-24 target | 20/25 | Dots included |
| Sites with a non-carousel sub-24 target | 18/25 | Dots excluded |
| Pages that scroll sideways | 4/25 | Up to +810px |
Site detail, sorted by non-carousel sub-24 targets. E04, E08, E16, E18 and E22 are zero on all seven columns and are omitted:
| Site | Non-inline | <24 | Non-carousel <24 | Dots <24 | Unnamed | Overflow |
|---|---|---|---|---|---|---|
| E30 | 34 | 23 | 23 | 0 | 0 | +810 |
| E20 | 19 | 16 | 16 | 0 | 0 | — |
| E03 | 37 | 15 | 10 | 5 | 0 | — |
| E02 | 15 | 9 | 9 | 0 | 6 | — |
| E23 | 30 | 17 | 9 | 8 | 0 | — |
| E01 | 11 | 7 | 7 | 0 | 5 | — |
| E28 | 12 | 6 | 6 | 0 | 0 | +732 |
| E17 | 25 | 5 | 5 | 0 | 4 | — |
| E26 | 17 | 5 | 5 | 0 | 0 | — |
| E11 | 6 | 4 | 4 | 0 | 1 | +14 |
| E25 | 4 | 4 | 4 | 0 | 4 | — |
| E27 | 18 | 4 | 4 | 0 | 0 | — |
| E13 | 4 | 3 | 3 | 0 | 0 | — |
| E24 | 77 | 3 | 3 | 0 | 0 | — |
| E12 | 9 | 4 | 2 | 2 | 0 | — |
| E29 | 9 | 2 | 2 | 0 | 2 | — |
| E09 | 2 | 1 | 1 | 0 | 0 | — |
| E14 | 9 | 6 | 1 | 5 | 0 | — |
| E06 | 39 | 18 | 0 | 18 | 0 | +220 |
| E19 | 7 | 4 | 0 | 4 | 0 | — |
Spacing exception: 78 pass, 78 still fail
WCAG 2.2 2.5.8 allows a spacing exception: a target under 24px passes when a 24px circle centred on it intersects neither another target's rectangle nor the circle of another undersized target. On 2026-11-09 between 18:40 and 18:45 we reran the same 25 homepages at the same 390x844 viewport and tested every small target; tangent contact counts as passing.
| Kind | <24px | Pass spacing | Still fail |
|---|---|---|---|
| Non-carousel controls | 114 | 75 | 39 |
| Carousel dots | 42 | 3 | 39 |
| Total | 156 | 78 | 78 |
Failures concentrate on 10 sites; the other 15 have none:
| Site | Still fail | Controls | Dots |
|---|---|---|---|
| E30 | 20 | 20 | 0 |
| E06 | 18 | 0 | 18 |
| E03 | 11 | 6 | 5 |
| E23 | 8 | 0 | 8 |
| E01 | 5 | 5 | 0 |
| E14 | 5 | 0 | 5 |
| E11 | 3 | 3 | 0 |
| E13 | 3 | 3 | 0 |
| E19 | 3 | 0 | 3 |
| E24 | 2 | 2 | 0 |
E02's nine 18px icons all pass because they sit far enough apart, while E01's five 14px icons fail as neighbours; all 18 of E06's dots fail, as do all 20 of E30's navigation links. Half of the 156 boxes clear the spacing exception, but 78 still need a larger target or more distance; the circle test is a geometric approximation, not a substitute for a manual tap test.
Four kinds of small target: icons, navigation, dots, arrows
| Kind | Anonymised example | Observation |
|---|---|---|
| Icon link | E01 five 14x14; E02 six 18x18 | No visible text; five of E01's seven small targets and six of E02's nine are unnamed |
| Navigation text | E28 155x10 and 101x10; E20 100x22; E30 64x16-19 | Hit box shorter than the visual text, which overflows the box |
| Carousel dot | E03 6-8px; E06 18 dots; E23 8; E19 4; E14 5; E12 2 | 42 matched by class, all below 24 |
| Carousel button (dot rule missed) | E24 three 8x8; E25 four 30x2-40x4 | Class is banner-dot / el-carousel, counted as non-carousel |
| Slider arrow | E12 18x35; E27 21x20; E26 8x21 | Narrower than 24, easy to mis-tap |
The quietest failure is not a small button but a box smaller than its text: E28 navigation links use a 16px font but a 10px line-height and box, so the hit area is thinner than the visible word. The other pattern is the icon link: 14-18px squares with no text and no aria-label; visible, but hard to hit. Dot classification relies on class names; seven carousel buttons in E24 and E25 missed the rule and were counted as non-carousel, so 42 is a floor rather than every dot.
22 small targets have no accessible name
Of the 156 sub-24 targets, 22 have no name: E01 5, E02 6, E17 4, E25 4, E29 2 and E11 1. The check only looks for aria-label, title, img alt, visible text and value; it does not judge whether the name is accurate. Icon fonts, CSS pseudo-elements and background images produce no name, so those buttons need an explicit aria-label; otherwise a screen reader reads only "link" and voice control cannot target it by name.
Sideways overflow: four sites, three above 100px
| Site | Document width at 390 | Overflow | What we saw |
|---|---|---|---|
| E30 | 1,200 | +810 | body width 1,200; a desktop layout moved to mobile unchanged |
| E28 | 1,122 | +732 | Main content 1,122; the right side of the navigation is cut off |
| E06 | 610 | +220 | Header and content exceed the viewport and are clipped on the right |
| E11 | 404 | +14 | Minor, less than one 16px character |
Screenshot rechecks of E28 and E30 both show clipped right-hand content rather than a responsive layout: E30's body computes to 1,200px and E28's main container to 1,122px. E06 runs 610px wide, while E11 is only 14px over. Fixed-position elements are excluded from the contributor list; if a site hides wide content with overflow:hidden, this metric reports no overflow, which is a different problem.
Acceptance checklist: measure the box before arguing spacing
- Use 24x24 as the floor and 44x44 as the recommendation. Add padding or a larger hit pseudo-element to icon links before debating visual size.
- Inline text links may be exempt; standalone controls are not. Navigation, buttons, dots and arrows do not get the 2.5.8 inline exception.
- Check names at the same time. Icon buttons need
aria-labelor visible text; an icon-only link cannot rely on guessing. - Measure
scrollWidthat 390px. A fixed 1,200px desktop layout cannot move to a phone unchanged; put wide tables in a scroll container instead of letting the whole page drag. See the mobile viewport pilot and semantics, keyboard access and ARIA. - Test the spacing exception separately. This run checked it: 78 pass and 78 still fail; tangent contact passes, but the geometric check does not replace a manual tap test.
Limitations
- The 25 sites are one equipment-homepage pilot, not the industry; 20 sites with a small target is a within-sample count.
- One snapshot: 2.5 seconds after
readyState. Autoplay, font loading and lazy loading change what sits in the viewport, and sizes are stable but not frame-identical. - Headless Chrome 390x844 at DPR 1 with a desktop UA, not real devices; no touch, scrolling, landscape or browser chrome.
- Boxes, not visual text;
transformscaling is reflected in the measured box, while icon fonts and pseudo-elements have no separate box. - 425 inline text links are excluded; the spacing exception is recomputed with rectangle/circle geometry, while keyboard, contrast, focus order and name accuracy are out of scope.
- Homepages only; inner pages, forms, modals and expanded mobile menus are not measured.
- The overflow metric reads
scrollWidthand does not detect clipping caused byoverflow:hidden.
Data and reproduction
Spacing recheck: equipment-homepage-spacing-exception-390-2026.csv (25 rows by 16 columns: under 24, pass/fail, controls/dots, unnamed and time). The repository keeps docs/research/2026-11-homepage-spacing-exception-390.csv.
Anonymised data: equipment-homepage-tap-targets-390-2026.csv (25 rows by 15 columns: controls, non-inline, inline, under 24, under 44, non-carousel, dots, unnamed, document width, overflow and time). The repository keeps docs/research/2026-11-homepage-tap-targets-390.csv. Thresholds and aggregation live in scripts/tap_target_probe.py, with eight assertions in scripts/test_tap_target_probe.py; the CSV contains no site URLs, titles or contact details.
Frequently asked questions
Is 24px mandatory?
WCAG 2.2 2.5.8 (AA) requires targets of at least 24x24 CSS px, with a spacing exception: a target may be smaller when a 24px circle centred on it does not overlap another target. This article measures the boxes and then applies the exception: of 156, 78 pass and 78 still fail. The 44/48 figures are Apple and Material recommendations, not the WCAG AA requirement.
Why are inline text links excluded?
WCAG 2.5.8 exempts links inside a sentence; counting the 425 inline links here would drown out the button problems. Standalone navigation, icon buttons, carousel dots and slider arrows get no such exemption.
Do carousel dots count?
They are controls. Forty-two dots are under 24px here and are listed separately. They are rarely the main path, but mis-taps are costly on a phone; if they stay, enlarge the hit area or show fewer pages.
Can 25 sites represent the equipment industry?
No. The 25 sites are a pilot from one equipment-homepage frame and cannot be generalised; the numbers show patterns and an acceptance method, not an industry rate.
Why did all 25 sites render this time?
This run used the Chrome DevTools Protocol, opening a new tab per site and waiting 2.5 seconds after readyState reached complete. The earlier dump-dom run failed on ten sites; the methods differ, so render counts are not comparable.
How is sideways scrolling decided?
documentElement.scrollWidth minus 390; anything above zero means the page can be dragged sideways. E30 is 1,200, E28 1,122, E06 610 and E11 404. Fixed-position elements are excluded from the contributor list; if a site clips with overflow:hidden, this metric reports no overflow and clipping needs a separate check.
Can the data be checked?
Yes. The public CSV has 25 rows and 16 columns (E01-E30, anonymised), and the aggregation rules live in scripts/tap_target_probe.py with 15 offline assertions; re-measure by sample_id.
How is the spacing exception calculated?
Centre a 12px-radius circle on the target box: the target fails if the circle intersects another target's rectangle; when the other target is also undersized, compare the two circles, failing below a 24px centre distance and passing when tangent. It is a geometric check, not a page-script test or a manual tap test.