Modern QA2026Touch Target Sizing — tiles
Log inJoin
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])