Доступность
Приложения должны быть доступны всем: слабовидящим, людям с ограниченными возможностями.
accessibilityLabel
Текстовое описание элемента для screen reader:
<Pressable
onPress={onClose}
accessibilityLabel="Закрыть"
accessibilityRole="button"
>
<Ionicons name="close" size={24} />
</Pressable>
Без label скринридер прочитает имя иконки, а не её значение.
accessibilityRole
Роль элемента:
accessibilityRole="button"
accessibilityRole="link"
accessibilityRole="header"
accessibilityRole="image"
accessibilityRole="text"
accessibilityRole="search"
accessibilityRole="checkbox"
accessibilityRole="radio"
accessibilityRole="switch"
accessibilityRole="tab"
accessibilityRole="menu"
accessibilityRole="alert"
accessibilityState
Состояние:
<Pressable
accessibilityState={{
disabled: isDisabled,
selected: isSelected,
checked: isChecked,
busy: isLoading,
expanded: isExpanded,
}}
>
accessibilityHint
Подсказка о том, что произойдёт:
<Pressable
accessibilityLabel="Удалить"
accessibilityHint="Удаляет запись без возможности восстановления"
onPress={onDelete}
>
<Text>Удалить</Text>
</Pressable>
accessibilityLiveRegion
Уведомление об изменениях:
<Text accessibilityLiveRegion="polite">
Сохранено
</Text>
<Text accessibilityLiveRegion="assertive">
Ошибка!
</Text>
polite — после текущего чтения. assertive — немедленно.
accessible
Группировка элементов:
<View accessible accessibilityLabel="Карточка пользователя: Алиса, 25 лет">
<Text>Алиса</Text>
<Text>25 лет</Text>
</View>
Скринридер прочитает всё как один элемент.
Кнопки с иконками
<Pressable
onPress={onLike}
accessibilityRole="button"
accessibilityLabel={isLiked ? 'Убрать лайк' : 'Поставить лайк'}
accessibilityState={{ selected: isLiked }}
hitSlop={8}
>
<Ionicons name={isLiked ? 'heart' : 'heart-outline'} size={24} />
</Pressable>
Формы
<Text nativeID="email-label">Email</Text>
<TextInput
accessibilityLabelledBy="email-label"
placeholder="Введите email"
keyboardType="email-address"
accessibilityHint="Ваш email для входа"
/>
Минимальный размер области нажатия
44×44 px — Apple HIG, 48×48 dp — Material Design:
<Pressable
style={{ width: 48, height: 48, justifyContent: 'center', alignItems: 'center' }}
onPress={onClose}
>
<Ionicons name="close" size={24} />
</Pressable>
Или hitSlop:
<Pressable hitSlop={{ top: 12, bottom: 12, left: 12, right: 12 }} onPress={onClose}>
Контраст
Текст должен быть читаемым:
- AA: контраст 4.5:1 для обычного, 3:1 для крупного
- AAA: 7:1 для обычного, 4.5:1 для крупного
Инструменты: WebAIM Contrast Checker, Stark.
Динамический размер шрифта
Пользователь может увеличить шрифт в настройках. React Native учитывает это автоматически.
Отключить:
<Text allowFontScaling={false}>Текст</Text>
Но лучше не отключать — доступность важнее.
Screen reader
- iOS: VoiceOver
- Android: TalkBack
Включить в настройках или через меню разработчика.
Тестирование
- Включи VoiceOver или TalkBack
- Пройди по приложению с закрытыми глазами
- Проверь, что все элементы озвучиваются
- Проверь порядок фокуса
- Проверь, что кнопки нажимаются
Итоги
accessibilityLabelдля элементов без текстаaccessibilityRoleдля типаaccessibilityStateдля состоянияaccessibilityHintдля подсказок- 44×44 минимум для нажатия
- Тестируй со screen reader