Implementing Accessibility
1. Using Accessibility Props
| Prop | Description | Values | Notes |
|---|---|---|---|
| accessibilityLabel | Defines a string that labels the component for accessibility | string |
Used by screen readers to identify the component |
| accessibilityHint | Provides a hint to the user about how the component can be used | string |
Reads after the label by screen readers |
| accessibilityRole | Defines the semantic role of the component | 'button', 'image', 'text', 'link', etc. |
Overrides default role detection |
| accessibilityState | Indicates the current state of the component | { selected: true }, { disabled: true } |
Used for dynamic state changes |
| importantForAccessibility | Controls whether the component is included in accessibility tree | 'auto', 'yes', 'no', 'no-hide-descendants' |
Useful for hiding elements visually but keeping them accessible |
Example: Using accessibilityLabel and accessibilityRole
<Button
accessibilityLabel="Press to submit form"
accessibilityRole="button"
onPress={handleSubmit}
>
Submit
</Button>
Example: Using accessibilityState for toggle buttons
<TouchableOpacity
accessibilityRole="button"
accessibilityState={{ selected: isToggled }}
onPress={() => setIsToggled(!isToggled)}
>
<Text>{isToggled ? "On" : "Off"}</Text>
</TouchableOpacity>
2. Setting Accessibility Roles
| Role | Description | Usage |
|---|---|---|
| accessibilityRole | Defines the semantic role of the element for assistive technologies. | <View accessibilityRole="button"> |
| accessibilityState | Indicates the current state of the element (e.g., disabled, checked). | <View accessibilityState={{disabled: true}}> |
| accessibilityValue | Provides the current value of a control or element. | <View accessibilityValue={{text: "50%"}}> |
Example: Button Role
<TouchableOpacity accessibilityRole="button" onPress={handlePress}>
<Text>Press Me</Text>
</TouchableOpacity>
Example: Slider Role
<Slider
accessibilityRole="adjustable"
value={value}
onValueChange={setValue}
accessibilityValue={{text: `${value}%`}}
></Slider>
3. Using Accessibility Hints
| Property | Values | Description |
|---|---|---|
| accessibilityHint | string |
Provides a brief description of what happens when the user interacts with the component. |
Example: Setting an Accessibility Hint
<TouchableOpacity
accessibilityHint="Taps this button to navigate to the next screen"
onPress={handlePress}
>
<Text>Next</Text>
</TouchableOpacity>
Note: The
accessibilityHint is used in conjunction with accessibilityLabel to provide more context for users who rely on assistive technologies.
4. Managing Focus Order
| Property | Description | Notes |
|---|---|---|
| accessibilityFocus | Controls whether an element should receive focus when the screen reader focuses on it. | Useful for elements that are visually hidden but need to be accessible to screen readers. |
| accessibilityRole | Defines the semantic role of an element for accessibility purposes. | Can be used to override default roles or define custom roles. |
| accessibilityState | Indicates the current state of an element (e.g., checked, disabled). | Used to communicate dynamic states to assistive technologies. |
Example: Setting Focus Order
<View
accessibilityRole="button"
accessibilityFocus={true}
accessible={true}
>
<Text>Press me</Text>
</View>
Note: The
accessibilityFocus property is particularly useful in complex UIs where the default focus order does not align with the intended navigation flow.
5. Announcing Changes
| Property | Description | Values | Notes |
|---|---|---|---|
| announcedText | Text to be announced by screen readers | string |
Used for dynamic content updates |
| announcedAccessibilityState | Accessibility state that triggers announcement | object |
Can include expanded, selected, etc. |
Example: Using announcedText
<View accessible={true} accessibilityLabel="Updated content">
<Text accessibilityAnnouncement="Content has been updated">
New content here
</Text>
</View>
Note: The
accessibilityAnnouncement prop is used to announce changes to screen readers.
6. Using Semantic Elements
| Element | Description | Accessibility Impact | Notes |
|---|---|---|---|
<View> |
Base container component | Generic container, no semantic meaning | Use with accessibilityRole for semantic context |
<Text> |
Displays text content | Provides text content for screen readers | Supports accessibilityRole="header" for headings |
<Button> |
Interactive button component | Automatically announces as a button | Use accessibilityLabel for custom labels |
<Image> |
Displays images | Requires alt or accessibilityLabel |
Improves accessibility when labeled appropriately |
<ScrollView> |
Scrollable content container | Announced as scrollable region | Use accessibilityRole="scrollview" to clarify |
<FlatList> |
Performance-focused list component | Announced as list with items | Use accessibilityLabel for list structure |
Example: Using Semantic Elements with Accessibility Roles
<View accessibilityRole="main">
<Text accessibilityRole="header">Welcome to Expo</Text>
<Button
title="Press Me"
accessibilityLabel="Press this button to continue"
/>
</View>
Note: Always provide semantic context using
accessibilityRole when the default role is not sufficient.
7. Supporting Screen Readers
| Property | Description | Values |
|---|---|---|
| accessibilityLabel | Defines the text that is read by screen readers for an element | string |
| accessibilityHint | Provides a hint to the user about what will happen when they interact with an element | string |
| accessibilityRole | Defines the role of an element for screen readers (e.g., button, heading) | button, heading, image, link, text |
| accessibilityState | Indicates the state of an element (e.g., disabled, selected) | { disabled: boolean, selected: boolean } |
Example: Using accessibilityLabel
<Button
title="Submit"
accessibilityLabel="Press to submit form"
onPress={handleSubmit}
>
</Button>
Example: Using accessibilityRole
<View accessibilityRole="heading">
<Text>Welcome to Expo</Text>
</View>
Note: Ensure all interactive elements have appropriate accessibility roles and labels for screen reader users.
Best Practices for Screen Reader Support
- Always provide
accessibilityLabelfor custom components or non-standard UI elements - Use
accessibilityRoleto define semantic roles for screen readers - Include
accessibilityHintto provide context about the action of an element - Avoid relying solely on visual cues for accessibility
8. Setting Minimum Touch Target
| Property | Value | Description |
|---|---|---|
| hitSlop | object |
Defines the touchable area around a component. Accepts {top, left, bottom, right} in points. |
| accessibilityRole | button |
Indicates that the component is a button for accessibility purposes. |
Example: Using hitSlop for Touch Targets
<TouchableOpacity
hitSlop={{ top: 10, left: 10, bottom: 10, right: 10 }}
onPress={() => console.log('Tapped!')}
>
<View style={{ padding: 20 }}>
<Text>Press Me</Text>
</View>
</TouchableOpacity>
Note: The
hitSlop property is essential for ensuring that touch targets meet accessibility guidelines, especially on smaller screens or for users with motor impairments.
9. Using High Contrast Mode
| Property | Description | Values |
|---|---|---|
| accessibilityBackgroundColor | Defines the background color for high contrast mode | ColorValue |
| accessibilityTextColor | Defines the text color for high contrast mode | ColorValue |
Example: Setting High Contrast Colors
import { View, Text } from 'react-native';\n\n<View\n accessibilityBackgroundColor="#000"\n accessibilityTextColor="#fff"\n>\n <Text>High contrast text</Text>\n</View>
Note: High contrast mode is controlled by the OS settings and may not be available on all platforms.
10. Testing Accessibility
Example: Using axe-core for accessibility testing
import { axe } from 'axe-core';
const results = await axe.run(document);
console.log(results.violations);
| Test Type | Description | Tool | Notes |
|---|---|---|---|
| Screen Reader | Simulates user interaction with screen readers | axe-core |
Can be integrated into CI/CD pipelines |
| Color Contrast | Checks for sufficient color contrast ratios | axe-core |
Ensures readability for visually impaired users |
| Keyboard Navigation | Verifies keyboard accessibility | axe-core |
Tests tab order and focus management |
Note: axe-core is a powerful open-source library that helps identify accessibility issues in web and mobile applications.
Accessibility Testing Tools Comparison
- axe-core: Open-source, supports multiple platforms
- Accessibility Insights: Microsoft's tool for web and mobile
- WAVE: Web Accessibility Evaluation Tool
11. Using Accessibility Scanner (Android)
| Feature | Description | Notes |
|---|---|---|
| Scan Mode | Full Scan |
Scans entire screen for accessibility issues |
| Scan Results | Accessibility Issues |
Lists issues with severity levels |
| Export Report | JSON Format |
Export scan results for analysis |
Note: Requires Android 8.0 or higher
Warning: Accessibility Scanner is not officially supported by Expo
Key Features
- Full screen scanning capability
- Severity-based issue classification
- Export functionality for detailed reporting
12. Implementing Focus Management
| Property | Description | Usage |
|---|---|---|
| accessibilityFocus | Indicates that a component should receive focus when the screen reader focuses on it. | accessibilityFocus can be used to programmatically set focus on a component. |
| accessibilityRole | Defines the role of a component for accessibility purposes. | Used to define semantic roles like button, link, etc. |
| accessibilityState | Represents the current state of a component for accessibility. | Used to indicate states like disabled, expanded. |
Example: Setting Focus Programmatically
import React, { useRef } from 'react';
import { View, Button } from 'react-native';
const FocusExample = () => {
const focusableRef = useRef(null);
const handleFocus = () => {
if (focusableRef.current) {
focusableRef.current.setNativeProps({ accessibilityFocus: true });
}
};
return (
<View>
<Button title="Focus Button" onPress={handleFocus} />
<View ref={focusableRef} accessibilityRole="button">
<Text>This component can receive focus</Text>
</View>
</View>
);
};
Note: Focus management in React Native is handled through native props and accessibility roles. Ensure that focusable elements are properly labeled for screen readers.