62 / 66 · 09 Mobile & Cross-Platform Testing · Mobile Accessibility Testing← prev⊞ allnext →☰ Read as one page
11.3Touch Target Sizing
WCAG 2.2 requires a minimum touch target size of 24x24 CSS pixels. Apple recommends 44x44 points. Google recommends 48x48 dp. These are minimum sizes -- larger targets are always better.
def test_minimum_touch_target_size(driver):
"""All interactive elements must meet minimum touch target requirements."""
# Platform-specific minimum sizes
platform = driver.capabilities.get("platformName", "").lower()
min_size = 44 if platform == "ios" else 48 # points (iOS) or dp (Android)
interactive_elements = (
driver.find_elements(AppiumBy.CLASS_NAME, "XCUIElementTypeButton") +
driver.find_elements(AppiumBy.CLASS_NAME, "XCUIElementTypeLink") +
driver.find_elements(AppiumBy.CLASS_NAME, "XCUIElementTypeSwitch")
)
violations = []
for el in interactive_elements:
rect = el.rect
if rect["width"] < min_size or rect["height"] < min_size:
label = el.get_attribute("label") or "unknown"
violations.append(
f"'{label}' is {rect['width']}x{rect['height']}, "
f"minimum is {min_size}x{min_size}"
)
assert len(violations) == 0, \
f"Touch target violations:\n" + "\n".join(violations)
def test_touch_targets_have_adequate_spacing(driver):
"""Touch targets should have at least 8dp spacing between them."""
min_spacing = 8
buttons = driver.find_elements(AppiumBy.CLASS_NAME, "XCUIElementTypeButton")
rects = [(b, b.rect) for b in buttons if b.is_displayed()]
violations = []
for i, (el_a, rect_a) in enumerate(rects):
for el_b, rect_b in rects[i+1:]:
# Calculate gap between elements
h_gap = max(0, max(rect_b["x"] - (rect_a["x"] + rect_a["width"]),
rect_a["x"] - (rect_b["x"] + rect_b["width"])))
v_gap = max(0, max(rect_b["y"] - (rect_a["y"] + rect_a["height"]),
rect_a["y"] - (rect_b["y"] + rect_b["height"])))
if h_gap < min_spacing and v_gap < min_spacing:
label_a = el_a.get_attribute("label") or "?"
label_b = el_b.get_attribute("label") or "?"
violations.append(
f"'{label_a}' and '{label_b}' are only "
f"{min(h_gap, v_gap)}dp apart (minimum {min_spacing}dp)"
)
assert len(violations) == 0, \
f"Spacing violations:\n" + "\n".join(violations[:10])