Touch targets must be at least 24×24 CSS px or have 24px clear separation from other targets
Intro:
Interactive targets must present a minimum 24 by 24 CSS pixel hit area, or be spaced so a 24px-diameter circle centered on each target does not overlap other targets. This affects links, buttons, icons, and other tappable controls, especially on mobile. Users with limited dexterity or larger fingers are at highest risk when targets are small or crowded.
Why It Matters
Small or tightly packed targets cause mis-taps. People with tremors, reduced fine motor control, or situational limitations (walking, bumpy transit, gloves) struggle to activate the intended control.
On touch screens, there is no hover precision. A larger, well-spaced hit area reduces errors and frustration, improving task completion rates and reducing support requests.
Common Causes
- Icon-only buttons sized to the icon (e.g., 12–16px) without padding
- Negative margins or tight layout that collapses space between adjacent controls
- Overlapping or hidden elements that steal taps (e.g., absolute-positioned layers)
- Text links styled with small
line-heightor dense link groups - Tiny close/dismiss controls on dialogs, banners, or toasts
- Touch targets constrained by rigid grid systems without responsive adjustments
How to Fix
- Make the hit area at least 24×24 CSS pixels:
- Add padding to anchors and buttons so the clickable box meets or exceeds 24×24.
- For SVG/icon controls, keep the visual icon small but enlarge the interactive box with padding or a wrapper.
- Provide sufficient separation when targets are smaller than 24×24:
- Ensure a virtual circle with a 24px diameter centered on each target does not intersect other targets. A practical approach is adding at least 12px of clear space around undersized targets in all directions.
- Avoid overlap and crowding:
- Remove negative margins that collapse gaps. Use layout gaps (gap in flex/grid) or positive margins.
- Ensure no overlapping layers capture taps; set
pointer-events: noneon decorative overlays.
- Respect CSS pixels:
- Base measurements on CSS pixels, not device pixels. Verify computed sizes in DevTools.
- Responsive behavior:
- Check smaller breakpoints. Increase padding or spacing on mobile to keep the minimum.
Recommendation (WCAG 2.2):
- Meeting WCAG 2.2 AA Target Size (Minimum) can be achieved by 24×24 targets or the non-overlapping 24px circle rule. While exceptions exist (e.g., inline links, essential functionality, user-agent controls), design to meet the requirement wherever feasible.
How to Test
Keyboard check:
- Tab through interactive elements. Each control should be focusable with a visible focus indicator. While target size is a touch criterion, keyboard operability ensures consistent semantics.
Screen reader check:
- Confirm each target has an accessible name and role (e.g., buttons announce their purpose). Size is not announced, but correct semantics ensure no hidden overlaps.
Mobile/touch check:
- On a phone, tap near the edges of each control. You should not trigger a neighboring control.
- Use browser DevTools to inspect the computed box (width/height) of the target. Verify at least 24×24 CSS px or adequate clear space around smaller targets.
- Zoom to 200% and repeat taps to catch crowding issues.
Simple checklist:
- Measure hit box: ≥24×24 CSS px, or pass the 24px-circle separation rule.
- No overlapping clickable regions or negative margins crowding controls.
- Adequate gap between adjacent targets at all breakpoints.
- Focus outline clearly surrounds only the intended control.
- Icon buttons have padding; tiny close icons are wrapped to enlarge the hit area.
Good Example
<style>
.toolbar {
display: flex;
gap: 12px; /* clear space between targets */
}
.tap-target {
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 24px;
min-height: 24px;
padding: 8px; /* increases hit area well beyond 24px */
border-radius: 6px;
border: 1px solid #888;background: #fff;
}
.tap-target svg { width: 16px; height: 16px; pointer-events: none; }
</style>
<nav class="toolbar">
<button class="tap-target" aria-label="Add item">
+
</button>
<button class="tap-target">Save</button>
<a class="tap-target" href="#more" aria-label="More options">⋯</a>
</nav>
Why it’s good:
- Each control’s interactive box is ≥24×24 CSS px.
- Gap ensures targets cannot be accidentally activated together.
Bad Example
<style>
.inline-actions { display: inline-flex; }
.icon-btn {
width: 16px; height: 16px; /* too small */
padding: 0; /* no added hit area */
margin-right: -6px; /* crowds adjacent target */
border: none; background: transparent;
}
</style>
<div class="inline-actions">
<button class="icon-btn" aria-label="Add">+</button>
<button class="icon-btn" aria-label="Remove">–</button>
</div>Why it’s bad:
- Targets are smaller than 24×24 CSS px.
- Negative margin reduces separation, increasing mis-taps.
Quick Checklist
- Hit area is at least 24×24 CSS px for all primary controls.
- Undersized targets have a 24px-diameter clear zone that doesn’t intersect others.
- No negative margins or overlapping layers near interactive elements.
- Icon-only buttons include padding or a larger clickable wrapper.
- Adequate spacing is maintained across responsive breakpoints.
- Verified by tap testing on real devices and measuring in DevTools.