Touch target size and spacing for native apps
Minimum and recommended hit areas (44×44 pt iOS, 48×48 dp Android, WCAG 2.2 AA 24×24 px floor), spacing between targets, using minWidth/minHeight rather than relying on hitSlop, and how to verify with Accessibility Inspector and Accessibility Scanner.
Overview
What: How large tappable areas must be and how far apart.
Why: Small or crowded targets cause mis-taps for everyone and block people with limited dexterity. Apple's default control size is 44×44 pt (minimum 28×28 for special cases) with ~12 pt padding around bezelled elements and ~24 pt around unbezelled ones; Android requires 48×48 dp; WCAG 2.2 SC 2.5.8 sets a 24×24 CSS-px floor (with a spacing exception) and 2.5.5 (AAA) recommends 44×44.
Use when: every interactive element: icon buttons, chips, checkboxes, links in rows, close buttons on sheets.
Exceptions are rare: inline text links and dense pointer-only (iPad trackpad/desktop) contexts.
Implementation
- Targets: use 44×44 pt on iOS and 48×48 dp on Android as the minimum hit area for every control; for cross-platform code, use 48 for both unless the design is iOS-only.
- Visual vs hit size: a 24dp icon can sit inside a 48dp pressable:
<Pressable style={{ minWidth: 48, minHeight: 48, alignItems: 'center', justifyContent: 'center' }}
accessibilityRole="button" accessibilityLabel="Add tag" onPress={addTag}>
<Icon name="plus" size={24} />
</Pressable>
- Prefer real layout size over
hitSlop.hitSlopcan't extend beyond the parent's bounds, can overlap neighbours, and scanners measure the element's bounds — so a 24dp view with hitSlop may still fail audits. - Spacing: ≥ 8dp between adjacent targets (Material/Android guidance); more between a frequent action and a destructive one: about 12–16dp or a divider (judgement default above the 8dp minimum; no platform publishes a figure).
- Chips and segmented controls: visual height 32dp is acceptable if the pressable area extends to 48dp vertically within the row.
- Thumb reach: put frequent actions in the lower half on phones (tab bar, bottom toolbar, floating add button ≥ 56dp); reserve the top corners for infrequent actions (Edit, Settings).
- Edges: keep swipeable controls outside the system gesture insets: read
WindowInsets.systemGestures(or the mandatory system gesture insets) at runtime on Android, and respect the safe area and home indicator on iOS. If you cannot query them, use at least 16dp as a fallback. - Press feedback: visible pressed state within 100 ms (opacity/ripple via
android_ripple), and keep the press active if the finger drifts slightly (Pressable's default press-retention offset).
Web views and the WCAG floor (added in 1.1.0, merge request from the product lane). Any web view embedded in the app must meet WCAG 2.2 SC 2.5.8 Target Size (Minimum), Level AA: every pointer target is at least 24×24 CSS px, or is spaced so that a 24 CSS px diameter circle centred on it does not intersect another target or another undersized target's circle, with five narrow exceptions (inline text links, user-agent controls, essential presentation, equivalent alternatives, spacing). The unit is CSS pixels, explicitly independent of device pixel ratio and zoom: a control that is 24 physical pixels on a 3× screen is far too small. Treat 44×44 CSS px as the practical default in web views, matching the native 44 pt / 48 dp floors from the HIG and Material accessibility pages this item already cites as primary sources.
Verification
- iOS Accessibility Inspector audit and Xcode
performAccessibilityAudit()report no hit-region issues. - Android Accessibility Scanner reports no "touch target" findings on every screen of the state gallery.
- Manual: every icon-only control measured ≥ 44pt / 48dp (layout inspector or debug overlay).
- No adjacent targets closer than 8dp. Review prompt: are destructive actions separated further (about 12–16dp or a divider)?
- Primary actions reachable with one thumb on a 6.7" phone.
- Embedded web views: every control ≥ 24×24 CSS px or passes the 24px-circle spacing test (target 44), measured in CSS pixels at 1× zoom.
- Edge-swipe controls sit outside the runtime system gesture insets.
Sources:
- https://developer.apple.com/design/human-interface-guidelines/accessibility
- https://developer.android.com/guide/topics/ui/accessibility/apps
- https://www.w3.org/WAI/WCAG22/Understanding/target-size-minimum.html
- https://reactnative.dev/docs/pressable
- https://support.google.com/accessibility/android/answer/6376570
- https://support.google.com/accessibility/android/answer/7101858
- https://developer.android.com/develop/ui/views/touch-and-input/gestures/gesturenav
Limitations
- 44 pt ≈ 44 dp in physical size on typical densities, but not identical; 48 is the safe cross-platform value.
- Dense professional tools (spreadsheets, editors) on tablets with pointers may justify smaller targets when a touch alternative exists.
- WCAG 2.5.8's 24px floor is a minimum for conformance, far below platform recommendations; meeting WCAG alone isn't good mobile design.
- Scanners can't judge reach or spacing adequacy — manual review remains necessary.
- Values verified 2026-09-26: 22 values checked, 21 against standards and platform documentation and 1 against published guidelines; 3 were corrected in this revision. Remaining judgement defaults are marked as such in the text.