target-size-minimum
Pointer targets must be at least 24x24px large, or leave sufficient distance to other targets
Checks that pointer-operable targets have an effective hit region of at least 24 by 24 CSS pixels, or meet an allowed exception (e.g. sufficient spacing).
Applies to. Applies to <button>, <summary>, <a href>, <area href>, <input>, <select>, <textarea> and elements whose role resolves to button or link (the first real role in the role attribute, in any case) that are pointer-reachable: rendered, not suppressed by pointer-events:none, and with something left for a pointer to hit (a target clipped away is none; one with display: contents is its content). Accessibility-tree exclusion isn't a filter here: an aria-hidden control is still a target a pointer can hit. <area> is matched but never actually evaluated: it has no box of its own to measure. A custom element whose ElementInternals give it the button or link role (this.attachInternals().role), with no role attribute naming another, counts as a native element with that role does.
Expectation. Each target is at least 24 by 24 CSS pixels, or meets one of the SC 2.5.8 exceptions this rule can establish from geometry. A target is the region a pointer can hit: its border box with its rounded corners and 2D transforms, clipped by clip and clip-path: inset() on its containing-block chain and no larger than a box there that clips its overflow, with content sticking out of it. What is painted over a target takes nothing from it, another target included: whether a decorative layer, an overlay or a pinned row covers a target depends on the moment and the scroll position of the scan, so it says nothing about the target's size, and 2.5.8 measures the target itself. Two targets that overlap are within each other's circle, so an undersized one is still too close. A box that clips its overflow (overflow other than visible, or contain: paint), scrolled by the reader or by a script, doesn't cut it where its edge is now: the target is measured whole, as scrolled into it, no larger than the box, and only the boxes and targets inside the box are near a target it keeps out of view. It is large enough when a 24 by 24 square aligned to the page fits in that region, as Understanding 2.5.8 measures it. The exceptions: spacing (a 24px-diameter circle centred on the region's bounding box reaches no unrelated target's region, nor the circle of another undersized one), the inline exception for a target in a sentence, a link or a button written into the text (the stretch of its block container between line breaks holds text outside any target with a letter or a digit in it), or user-agent sizing (an unstyled native checkbox or radio, detected by appearance not having been reset to none). An undersized target too close to a neighbour fails. Where an exception may apply but cannot be confirmed (two inline links crowding each other between separators alone, as in "Edit | Delete", or a target inside an SVG, canvas or image map that may be essential), the result is cantTell rather than a guess. Margin (target-size-px): of the targets that are at least 24 by 24, the smallest, as the side of the largest square that fits in it against 24 (for a rectangle, the smaller of its width and height); context.widthPx and context.heightPx give its extent. A target under 24 that passes through the spacing exception is not a candidate. Only a target within 6px of 24 (up to 30) counts as close, so a page whose smallest target is larger gives no margin. measuredCount counts every target measured.
What a finding reports.
metrics.widthPx,metrics.heightPx: the extent of the region a pointer can hit, in CSS pixels;metrics.squarePx: the side of the largest square that fits in it, againstmetrics.minSizePx(24). Rounded to a tenth, but down where that would reach the limit, so a size under 24 never reads as 24.metrics.decidedBy: what found the target too close to another:centerDistance, the circle of another undersized target, orregionDistance, another target's region within the circle.metrics.centerDistancePx,metrics.minDistancePx(centerDistance): the distance from the target's centre to its neighbour's, against the 24px it needs.metrics.regionDistancePx,metrics.minDistancePx(regionDistance): how far the neighbour's region is from the target's centre, against the circle's 12px radius.conflictWith: a selector for the neighbour it is too close to.measured.width,measured.height,measured.square: the region's extent and the largest square, unrounded.viewport.width,viewport.height: the viewport the page was laid out in, in CSS pixels. A responsive page can size or place a target differently at another width.
These data.details fields help to read and reproduce a finding. Apart from reasonCode and the few fields Output schema names as stable, they are not a stable contract: a field may be renamed or dropped in a minor release, so don’t build on them.
Margin. This rule measures target-size-px in CSS pixels, and the value must reach the threshold. When a pass came near the threshold, the result’s margin names the element that came closest while still meeting it, so a pass that a small change would flip shows before it flips. Unlike the fields a finding reports, it is a stable contract. See Output schema.
Examples
<button style="width:24px; height:24px;">+</button>
Meets the 24×24 CSS pixel minimum on its own.
<button style="width:10px; height:10px; padding:0;">A</button><button style="width:10px; height:10px; padding:0; margin-left:5px;">B</button>
Both targets are 10×10, under 24×24, and their centres are 15px apart, closer than the 24px the spacing exception needs. (padding:0 matters: a browser's default button padding makes each one wider.)
How to check
When this rule can’t decide, it reports cantTell and leaves the question to a person. Each question it can ask is listed here under its reason code, with the steps to answer it. A finding carries the same steps as howToCheck, in the scan’s language. See Output schema.
undersized-inline-link-run
- Find the link the report names on the page, and the link next to it that it is too close to.
- Read the text the two links sit in, and decide whether they are part of a sentence or paragraph, which is exempt, or a row of links set apart only by separators such as "|" or "·", as in "Edit | Delete".
- If they are a row of links, inspect each in the developer tools' box model and check whether it is at least 24 by 24 CSS pixels, or whether a 24-pixel circle centred on it would touch the other link or that link's circle.
- If a link is smaller and too close, look for another control on the same page that does the same thing and meets that size or spacing.
Pass. The links are part of a sentence or paragraph, or each is at least 24 by 24 CSS pixels or far enough from the other, or another control on the page that meets the size does the same thing.
Fail. The links form a row of their own, set apart only by separators, and one is smaller than 24 by 24 CSS pixels and so close to the other that their 24-pixel circles overlap, with no control elsewhere on the page that meets the size and does the same, which fails WCAG 2.5.8.
undersized-plausibly-essential
- Find the target the report names and the graphic it belongs to: an SVG drawing, a canvas or an image map (an image with clickable areas).
- Decide whether the target's size and position carry information that would be lost if it were made larger or moved apart, as the pins on a map or the points on a chart do.
- If they don't, inspect the target in the developer tools' box model and check whether it is at least 24 by 24 CSS pixels, or whether a 24-pixel circle centred on it would touch another target or the circle of another small target.
- If it is smaller and too close, look for another control on the same page that does the same thing and meets that size or spacing, such as a list of the map's places as links.
Pass. The target's size is essential to what the graphic shows, or the target is at least 24 by 24 CSS pixels or far enough from others, or another control on the page that meets the size does the same thing.
Fail. The target's size is not essential, it is smaller than 24 by 24 CSS pixels and so close to another target that their 24-pixel circles overlap, and no control elsewhere on the page that meets the size does the same, which fails WCAG 2.5.8.