Коротко: доступність застосунку перевіряють руками — на телефоні з увімкненим VoiceOver (iOS) або TalkBack (Android). Автоматичні сканери сайтів тут не допоможуть: у нативному застосунку немає HTML-сторінки, яку можна просканувати. Нижче — чек-лист із 12 пунктів, які варто пройти перед кожним релізом. Кожен пункт: що перевірити, як це зробити і що виправляти в коді.
Чек-лист спирається на ДСТУ EN 301 549 (розділ 11 «Програмне забезпечення») і критерії WCAG 2.2 рівня AA — саме за ними оцінюють доступність застосунків в Україні та ЄС.
Кому і навіщо це потрібно
Скрінрідером на телефоні користуються незрячі й слабкозорі люди, збільшеним шрифтом — люди старшого віку, керуванням перемикачами — люди з порушеннями моторики. Якщо кнопка «Оплатити» озвучується просто як «кнопка», людина не завершить покупку і не отримає послугу.
Для державних сервісів дотримання ДСТУ EN 301 549 уже обовʼязкове. Для бізнесу вимоги стануть обовʼязковими з ухваленням законопроєкту 14278, а компанії, що працюють на ринку ЄС, уже мають виконувати European Accessibility Act — він прямо поширюється на застосунки банків, інтернет-магазинів і транспорту.
Перед початком: як увімкнути засоби доступності
| Що | iOS | Android |
|---|---|---|
| Скрінрідер | Параметри → Доступність → VoiceOver | Налаштування → Спеціальні можливості → TalkBack |
| Швидке ввімкнення | Потрійне натискання бокової кнопки (налаштувати «Швидка команда доступності») | Утримати обидві кнопки гучності 3 секунди (після налаштування ярлика) |
| Великий шрифт | Доступність → Екран і розмір тексту → Більший текст | Спеціальні можливості → Розмір шрифту, Розмір елементів |
| Зменшення руху | Доступність → Рух → Зменшення руху | Спеціальні можливості → Вилучити анімацію |
Основні жести скрінрідера (однакові на обох платформах): свайп вправо / вліво — наступний / попередній елемент, подвійний дотик — активувати. Порада: перш ніж тестувати свій застосунок, 10 хвилин покористуйтеся з VoiceOver чи TalkBack звичайними застосунками — так ви зрозумієте, як «має бути».
Чек-лист: 12 пунктів
1. Кожна кнопка й іконка має зрозумілу назву
Що перевірити: пройдіть екран свайпами. Кожен елемент має озвучуватися осмислено: «Кошик, 3 товари, кнопка», а не «кнопка», «зображення» чи «ic_cart_24».
Типові помилки: кнопки-іконки без підпису (пошук, закрити, показати пароль, «більше»), декоративні картинки, які скрінрідер зачитує, назва, що дублює роль («кнопка Кнопка купити»).
Як виправити:
// iOS (UIKit)
cartButton.accessibilityLabel = "Кошик"
cartButton.accessibilityValue = "3 товари"
decorativeImage.isAccessibilityElement = false
// SwiftUI
Image(systemName: "cart").accessibilityLabel("Кошик")
// Android (View)
cartButton.contentDescription = "Кошик, 3 товари"
decorativeImage.importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_NO
// Jetpack Compose
Icon(Icons.Default.ShoppingCart, contentDescription = "Кошик")
Image(painter, contentDescription = null) // декоративне зображення
Критерії: WCAG 1.1.1 «Нетекстовий контент», 4.1.2 «Назва, роль, значення».
2. Ролі та стани озвучуються
Що перевірити: скрінрідер каже не лише назву, а й що це за елемент і в якому він стані: «Сповіщення, перемикач, увімкнено», «Доставка курʼєром, вибрано», «Розгорнуто».
Типова помилка: «кнопка» зроблена з тексту чи картинки з обробником натискання — скрінрідер не знає, що це кнопка.
Як виправити: використовуйте стандартні компоненти (Button, Toggle, Switch, Checkbox) — у них ролі й стани вже є.
Для власних компонентів задайте роль явно: accessibilityTraits = .button (iOS), Modifier.semantics { role = Role.Button }
або Modifier.toggleable(...) (Compose), accessibilityRole="button" і accessibilityState={{ checked }} (React Native).
Критерій: WCAG 4.1.2.
3. Порядок фокуса логічний і фокус не губиться
Що перевірити: свайпами пройдіть екран від початку до кінця. Порядок має відповідати тому, як екран читається очима: заголовок → вміст → дії. Відкрийте й закрийте модальне вікно, додайте товар у кошик, перейдіть на інший екран — фокус має опинятися в логічному місці, а не «стрибати» на початок чи під модальне вікно.
Як виправити: групуйте повʼязані елементи (картка товару = один елемент із назвою, ціною й рейтингом):
shouldGroupAccessibilityChildren / accessibilityElements (iOS), Modifier.semantics(mergeDescendants = true) (Compose),
MergeSemantics (Flutter). Для модальних вікон — accessibilityViewIsModal = true (iOS); після відкриття нового
екрана повідомте систему: UIAccessibility.post(notification: .screenChanged, argument: titleLabel).
Критерії: WCAG 1.3.2 «Значуща послідовність», 2.4.3 «Порядок фокуса».
4. Заголовки розмічені як заголовки
Що перевірити: користувачі скрінрідера переходять між розділами екрана заголовками (ротор на iOS, меню навігації в TalkBack). Заголовки розділів мають озвучуватися як «заголовок».
Як виправити: accessibilityTraits = .header / .accessibilityAddTraits(.isHeader) (iOS),
Modifier.semantics { heading() } (Compose), android:accessibilityHeading="true" (View, API 28+),
Semantics(header: true, ...) (Flutter).
Критерій: WCAG 1.3.1 «Інформація та взаємозвʼязки».
5. Цілі дотику достатнього розміру
Що перевірити: кнопки, іконки, чекбокси, посилання в тексті — чи легко в них влучити пальцем.
| Орієнтир | Мінімум |
|---|---|
| Apple Human Interface Guidelines | 44 × 44 pt |
| Android / Material Design | 48 × 48 dp |
| WCAG 2.2, критерій 2.5.8 (рівень AA) | 24 × 24 CSS px або достатній відступ між цілями |
Як виправити: маленьку іконку можна лишити маленькою візуально, але збільшити область натискання
(padding, minimumInteractiveComponentSize у Compose, hitSlop у React Native).
6. Текст масштабується разом із системним налаштуванням
Що перевірити: увімкніть найбільший системний шрифт. Текст має збільшитися, а інтерфейс — не обрізати його, не накладати написи один на одного й не ховати кнопки за межі екрана.
Як виправити: iOS — Dynamic Type (UIFont.preferredFont(forTextStyle:) +
adjustsFontForContentSizeCategory = true, у SwiftUI стандартні стилі шрифтів масштабуються самі).
Android — розміри тексту в sp, не в dp; не фіксуйте висоту контейнерів із текстом. На Android 14+
перевіряйте масштаб до 200%.
Критерій: WCAG 1.4.4 «Зміна розміру тексту».
7. Контраст тексту й елементів керування
Що перевірити: звичайний текст — щонайменше 4,5 : 1 до фону, великий текст — 3 : 1, межі полів, іконки й стани елементів керування — 3 : 1. Окремо перевірте темну тему: у ній часто «зникають» сірі підписи й неактивні кнопки. Пару кольорів можна перевірити нашим інструментом перевірки контрасту.
Також: інформація не передається лише кольором (помилка в полі — не тільки червона рамка, а й текст).
Критерії: WCAG 1.4.3, 1.4.11, 1.4.1.
8. Складні жести мають просту альтернативу
Що перевірити: усе, що робиться свайпом, перетягуванням, щипком чи струшуванням телефона, можна зробити й звичайним натисканням. Приклади: видалити елемент свайпом → є ще кнопка «Видалити»; змінити порядок перетягуванням → є кнопки «вгору / вниз»; «струсніть, щоб скасувати» → є кнопка й цю функцію можна вимкнути.
Для скрінрідера: додайте власні дії до елемента (accessibilityCustomActions в iOS,
ViewCompat.addAccessibilityAction / customActions у Compose) — тоді «Видалити» доступне з меню дій.
Критерії: WCAG 2.5.1 «Жести вказівника», 2.5.4 «Активація рухом», 2.5.7 «Перетягування».
9. Форми: підписи, підказки й помилки
Що перевірити: кожне поле озвучує свою назву («Номер телефону, текстове поле»), а не лише плейсхолдер, що зникає після введення. Помилки озвучуються й пояснюють, що зробити: «Введіть 9 цифр після +380», а не просто «Помилка». Після відправки форми з помилкою фокус переходить до першої помилки.
Вхід і реєстрація: дозвольте вставляти пароль і код із буфера, підтримайте менеджери паролів і біометрію. Не вимагайте розвʼязувати головоломки чи переписувати символи з картинки без альтернативи.
Критерії: WCAG 3.3.1, 3.3.2, 3.3.8 «Доступна автентифікація» (новий у WCAG 2.2).
10. Динамічні зміни озвучуються
Що перевірити: коли щось зʼявляється без переходу на новий екран — «Товар додано в кошик», «Збережено», «Немає зʼєднання», завантаження завершилося, — скрінрідер має про це сказати.
Як виправити: iOS — UIAccessibility.post(notification: .announcement, argument: "Товар додано в кошик");
Android — live region (android:accessibilityLiveRegion="polite", у Compose Modifier.semantics { liveRegion = LiveRegionMode.Polite }).
Критерій: WCAG 4.1.3 «Повідомлення про стан».
11. Орієнтація, рух і таймаути
Що перевірити:
- застосунок працює і у вертикальній, і в горизонтальній орієнтації (виняток — коли орієнтація справді важлива, як у сканері документів);
- при ввімкненому «Зменшенні руху» зникають паралакс, автопрокручування банерів і великі анімації;
- якщо сесія чи код підтвердження мають обмеження часу, людина може продовжити час — скрінрідером усе робиться повільніше.
Як виправити: перевіряйте UIAccessibility.isReduceMotionEnabled (iOS) і налаштування масштабу анімацій (Android).
Критерії: WCAG 1.3.4 «Орієнтація», 2.2.1 «Регульований час», 2.3.3 (рекомендовано).
12. Відео, аудіо й системні налаштування
Що перевірити: у відео є субтитри (не лише автоматичні), в аудіо — текстова версія. Застосунок реагує на системні налаштування: жирний шрифт, збільшений контраст, інверсію кольорів — нічого не «ламається» і не стає нечитабельним. Застосунком можна керувати зовнішньою клавіатурою та перемикачами (Switch Control / Switch Access) — фокус видно.
Критерії: WCAG 1.2.2 «Субтитри», 2.1.1 «Клавіатура», 2.4.7 «Видимий фокус»; ДСТУ EN 301 549, п. 11.7 «Налаштування користувача».
Перевіримо ваш застосунок безкоштовно Фахівець ЦМЦІ пройде три ключові екрани з VoiceOver і TalkBack на реальних пристроях і надішле звіт із кроками відтворення та рекомендаціями — до 10 робочих днів.
Інструменти для тестування доступності мобільних застосунків
| Інструмент | Платформа | Що робить |
|---|---|---|
| Accessibility Inspector (у складі Xcode) | iOS | Показує назви, ролі й значення елементів, запускає автоматичний аудит екрана |
performAccessibilityAudit() у XCUITest (Xcode 15+) | iOS | Автоматичні перевірки доступності прямо в UI-тестах |
| Accessibility Scanner (застосунок Google) | Android | Знаходить маленькі цілі дотику, низький контраст, елементи без підпису |
Espresso AccessibilityChecks.enable() | Android | Перевірки доступності під час UI-тестів |
| Compose UI Check / Layout Inspector (Android Studio) | Android | Підсвічує проблеми доступності в макеті |
meetsGuideline(...) у flutter_test | Flutter | Тести на розмір цілей, підписи й контраст тексту |
| VoiceOver і TalkBack | обидві | Головний інструмент: жоден автотест не замінить проходження екрана скрінрідером |
Важливо: автоматичні перевірки знаходять лише частину проблем — переважно технічні (розмір, контраст, відсутній підпис). Логічність порядку фокуса, зрозумілість назв і те, чи можна взагалі пройти сценарій, перевіряє тільки людина. Детальніше про поєднання автоматичної й ручної перевірки — у статті Аудит доступності: що це і як проводять.
Особливості тестування мобільних застосунків на доступність
Чим тестування застосунку відрізняється від перевірки сайту:
- Немає універсального сканера. Сайт можна просканувати за хвилину, застосунок — тільки пройти руками на пристрої.
- Дві платформи — дві поведінки. Той самий екран на iOS і Android може озвучуватися по-різному, особливо на React Native і Flutter. Тестуйте на обох.
- Кросплатформні фреймворки мають власну розмітку доступності:
Semanticsу Flutter,accessibilityLabel/accessibilityRoleу React Native. Якщо її не задати, компонент буде «німим» на обох платформах. - Сценарії важливіші за екрани. Перевіряйте не окремі екрани, а шлях: вхід → пошук → оформлення → оплата. Одна недоступна кнопка посередині блокує весь сценарій.
- Системні налаштування. Застосунок має поважати налаштування телефона (шрифт, рух, контраст) — це окрема вимога ДСТУ EN 301 549 для програмного забезпечення.
Як вбудувати перевірку в процес розробки
- Дизайн: контраст, розмір цілей і підписи іконок закладаються в макеті — виправляти в коді дорожче.
- Розробка: стандартні компоненти замість саморобних; назва для кожної іконки — частина definition of done.
- Автотести: увімкніть
AccessibilityChecks(Android) іperformAccessibilityAudit()(iOS) у наявних UI-тестах. - Перед релізом: 15 хвилин на ключовий сценарій з VoiceOver і TalkBack за цим чек-листом.
- Після релізу: відгуки користувачів про доступність — окрема мітка в трекері.
Про те, як організувати такі перевірки в команді, — у статті Внутрішній аудит доступності для команд розробки.
Часті питання
Чи можна перевірити застосунок на доступність автоматично? Частково. Accessibility Inspector, Accessibility Scanner і автотести знаходять технічні проблеми — маленькі кнопки, низький контраст, елементи без підпису. Але чи можна пройти сценарій зі скрінрідером, перевіряє лише людина на пристрої.
За яким стандартом оцінюють доступність мобільних застосунків в Україні? За ДСТУ EN 301 549, розділ 11 «Програмне забезпечення». Там, де це застосовно, він спирається на критерії WCAG рівня AA. Для державних сервісів дотримання стандарту обовʼязкове.
Який мінімальний розмір кнопки в мобільному застосунку? Apple рекомендує 44 × 44 pt, Google — 48 × 48 dp. WCAG 2.2 на рівні AA вимагає щонайменше 24 × 24 CSS-пікселі або достатній відступ між сусідніми цілями.
Чи потрібно тестувати окремо iOS і Android, якщо застосунок на Flutter чи React Native? Так. VoiceOver і TalkBack по-різному читають ті самі компоненти, тому помилка може проявитися лише на одній платформі.
Скільки часу займає перевірка? Ключовий сценарій за цим чек-листом — 15–30 хвилин на кожну платформу. Повна перевірка всіх екранів займає більше.
Чи можна отримати перевірку застосунку безкоштовно? Так. ГО «Центр моніторингу цифрової інклюзії» безкоштовно перевіряє три екрани застосунку з VoiceOver і TalkBack і надсилає звіт на email. Заявка — на сторінці аудиту мобільних застосунків.
Не впевнені, що пройшли все? Надішліть посилання на застосунок у магазині й оберіть три екрани — ми перевіримо їх безкоштовно на реальних пристроях зі скрінрідерами.