Accessibility Best Practices
A condensed summary of the 25 most important best practices drawn from every page in this section.
Search across all documentation pages
A condensed summary of the 25 most important best practices drawn from every page in this section.
Name every interactive control: Provide accessibilityLabel, visible text, or accessibilityLabelledBy - icon-only buttons without names fail VoiceOver and store review.
Set the correct accessibilityRole: Use button for actions, link for navigation, header for section titles, and switch on native toggles - roles set user expectations.
Expose state with accessibilityState: Communicate selected, disabled, checked, and expanded - never rely on color alone for selection or errors.
Hide decorative content: Set accessible={false} and importantForAccessibility="no-hide-descendants" on ornaments, redundant chevrons, and background art.
Enforce 44×44 pt targets: Use minHeight, padding, or hitSlop on small visuals - touch and switch-control users need generous hit regions.
Centralize semantics in design system: AppButton, IconButton, and Field wrappers require labels at the type level - features should not reinvent raw Pressable patterns.
Forward accessibility props on primitives: Custom components accept and pass through accessibilityLabel, accessibilityHint, and accessibilityState like underlying Pressable.
Placeholder is not a label: TextInput needs a visible label or accessibilityLabelledBy - placeholder-only fields fail forms audits.
Announce meaningful dynamic updates: Use AccessibilityInfo.announceForAccessibility or accessibilityLiveRegion for cart counts, submit errors, and async completion - not every re-render.
Group list rows into one focus stop: Tappable cards should merge title, price, and metadata into a single label - reduce swipes for TalkBack and Switch Control.
Test VoiceOver on a physical iPhone: Simulator smoke is insufficient - rotor behavior, hint timing, and focus quirks appear on device.
Test TalkBack on a physical Android: importantForAccessibility and live regions differ from iOS - ship only after Android device walkthrough.
Query tests by role and name: React Native Testing Library getByRole('button', { name: 'Save' }) aligns CI with assistive tech - testID alone hides label gaps.
Run eslint-plugin-react-native-a11y in CI: Catch missing labels before review - treat lint as necessary, not sufficient.
Allow font scaling on body copy: allowFontScaling defaults true - never disable globally; cap dense UI with maxFontSizeMultiplier instead.
Use flexible layouts at large text sizes: Prefer minHeight, flexWrap, and column reflow over fixed height + numberOfLines={1} on primary labels.
Read font scale on app resume: PixelRatio.getFontScale() after AppState active - users change text size while your app is backgrounded.
Honor Reduce Motion: Subscribe to reduceMotionChanged and pass ReduceMotion.System to Reanimated timing and entering animations.
Never block tasks on animation: Users with reduce motion enabled must reach final UI state instantly - provide non-gesture alternatives for swipe actions.
Trap modal focus: Set accessibilityViewIsModal on sheets and dialogs; restore focus to the trigger on dismiss with setAccessibilityFocus.
Move focus on navigation changes: Master-detail selection, wizard steps, and post-submit success should land screen reader focus on the new primary heading.
Enable hardware keyboard traversal: focusable on actionable Pressable controls and returnKeyType="next" chains on forms - critical for iPad and DeX.
Run the audit checklist before RC: Tier 1–2 every release; score P0/P1/P1 - see Accessibility Audit Checklist.
Coordinate with animations policy: Pair AccessibilityInfo checks with Reanimated ReduceMotion.System - see Reduced Motion and Animations reduced motion.
Document known gaps for enterprise buyers: Track checklist scores per release; publish accessibility contact and remediation timeline - procurement asks before users do.
Stack versions: This page was written for React 19.2.3, React Native 0.86.0, and Expo SDK 57 (
expo~57.0.4).
Reviewed by Chris St. John·Last updated Jul 16, 2026