Mobile app accessibility is where good product teams quietly lose points. A website might get an automated scan and a remediation sprint, but the iOS and Android apps often ship on instinct: it looks fine on the designer's Pro Max, so it ships. Then a VoiceOver user opens it, the checkout button reads as just "button," focus jumps backward, and the contrast washes out in sunlight.
The good news is that the fundamentals are few and concrete. This guide covers the four that matter most in practice: screen reader support, touch target size, color contrast, and focus order. It also shows how each maps to EN 301 549, the standard the EU uses to enforce the European Accessibility Act, so you know which fixes are also legal obligations.
Screen readers: VoiceOver and TalkBack
Every interactive element your app draws needs a name, a role, and a current value that the screen reader can announce. On iOS this comes from the UIAccessibility API (accessibilityLabel, accessibilityTraits, accessibilityValue); on Android, from the accessibility node tree (contentDescription, roles, state). When you build standard SwiftUI or Jetpack Compose controls, you get most of this for free. The trouble starts with custom views: a tappable View with an icon and no label reads as nothing, or worse, as the raw asset filename.
Three failures account for most real-world screen reader bugs:
- Icon-only buttons with no label. A heart icon for "Save" announces as "button" with no purpose. Add an explicit label ("Save to favorites"), not the icon name.
- Decorative images that steal focus. Mark them hidden (
accessibilityElementsHidden/importantForAccessibility="no") so the reader skips them instead of announcing "image." - State that never updates. A toggle that flips visually but keeps announcing "off," or a spinner that never tells the user anything changed. Use accessibility values and live-region announcements so dynamic changes are spoken.
Test by turning the screen reader on and looking away from the screen. If you can complete the core task (sign in, add to cart, pay) using only swipes and the spoken output, you are most of the way there. This maps to WCAG 1.1.1 (Non-text Content), 4.1.2 (Name, Role, Value), and 4.1.3 (Status Messages), all carried into EN 301 549 for non-web software.
Touch target size and gesture alternatives
WCAG 2.2 introduced 2.5.8 Target Size (Minimum) at Level AA: interactive targets must be at least 24 by 24 CSS pixels, with exceptions for inline and adequately spaced targets. That is the conformance floor. The platform guidelines aim higher for usability (Apple recommends 44 by 44 points, Material Design 48 by 48 dp), and you should design to those rather than to the 24px minimum.
The classic offenders are a small "X" close button in a modal corner, densely packed list-row chevrons, and tiny stepper controls. A target can look small as long as its tappable area is padded out to the minimum, so increase the hit area rather than the icon.
WCAG 2.2 also added 2.5.7 Dragging Movements at Level AA: any action driven by dragging (reordering a list, a slider, swipe-to-delete) must have a single-pointer alternative that does not require dragging. If your only way to delete an item is a swipe gesture, add a visible delete action too. Users with motor impairments, and those using switch control, cannot reliably drag.
Color contrast on small, bright screens
Contrast requirements match the web: 4.5:1 for normal text, and 3:1 for large text (at least 18pt, or 14pt bold) and for UI components and graphical objects (WCAG 1.4.3 and 1.4.11). On mobile this bites harder because screens are viewed outdoors in glare and at arm's length. The 16px gray-on-white placeholder that passes review on a calibrated monitor becomes unreadable on a phone in sunlight.
Two patterns to watch: light gray secondary text (timestamps, captions, helper text) that dips below 4.5:1, and low-contrast component boundaries. A 2px border at 2:1 against the background means a low-vision user cannot find the input field at all. Check pairs early with the free contrast checker before they harden into your design tokens. And do not rely on color alone to signal state: an error field that only turns red fails 1.4.1, so pair it with an icon or text.
Focus order and visible focus
Focus order is the sequence in which a screen reader, external keyboard, or switch device moves through elements. It must follow a logical reading order, which for most layouts is the visual top-to-bottom, leading-to-trailing order. Custom layouts break this constantly: an absolutely positioned banner that reads last, a modal that lets focus escape to the screen behind it, or a tab bar that lands before the content the user just navigated to.
WCAG 2.2 added 2.4.11 Focus Not Obscured (Minimum) at Level AA: when an element receives focus, it must not be entirely hidden behind a sticky header, toolbar, or keyboard. On mobile, the on-screen keyboard covering the focused input is the textbook violation, so make sure the view scrolls the focused field into the clear. Keyboard and focus behavior matter even on touch devices, because many people pair Bluetooth keyboards or use switch access.
Group related elements so focus does not stop on every fragment. A price, a star rating, and a product name in one card can be combined into a single focusable element with a composed label, so the user hears "Wireless headphones, 4.5 stars, 79 euros" in one stop instead of three.
How this maps to EN 301 549 and the EAA
The European Accessibility Act (Directive (EU) 2019/882) has applied since 28 June 2025 to a range of consumer products and services, including e-commerce, banking, transport, and e-books. Where a mobile app delivers a covered service to EU consumers, it is in scope. Conformance is demonstrated through the harmonized standard EN 301 549, whose clause 11 applies WCAG success criteria to non-web software including native apps. The practical baseline is WCAG 2.2 Level A and AA.
That means the four areas above are not just UX niceties; they are the same criteria a regulator or auditor will check. WCAG 2.2 added other criteria worth knowing for apps too: 3.3.8 Accessible Authentication (Minimum) at AA (do not force a cognitive test like remembering a code; allow paste and biometrics), 3.3.7 Redundant Entry at A (do not make users re-enter data they already gave you), and 3.2.6 Consistent Help at A. For broader context on the standard, see our EN 301 549 overview.
Start by auditing your app's web companion and marketing site, the parts a tool can crawl, then run the manual mobile passes above. You can scan your web properties free with AccessScan to clear the automated issues, then spend your manual testing budget on the app behaviors no crawler can see: focus order, gesture alternatives, and whether a label actually makes sense out loud.