Академія
Практика

Чек-лист доступності мобільного застосунку: як протестувати iOS і Android

Покроковий чек-лист тестування доступності мобільного застосунку: VoiceOver і TalkBack, підписи кнопок, розмір цілей дотику, масштаб тексту, контраст, жести, форми. Для розробників і тестувальників. ГО ЦМЦІ.

· Оновлено · 10 хв читання

Коротко: доступність застосунку перевіряють руками — на телефоні з увімкненим VoiceOver (iOS) або TalkBack (Android). Автоматичні сканери сайтів тут не допоможуть: у нативному застосунку немає HTML-сторінки, яку можна просканувати. Нижче — чек-лист із 12 пунктів, які варто пройти перед кожним релізом. Кожен пункт: що перевірити, як це зробити і що виправляти в коді.

Чек-лист спирається на ДСТУ EN 301 549 (розділ 11 «Програмне забезпечення») і критерії WCAG 2.2 рівня AA — саме за ними оцінюють доступність застосунків в Україні та ЄС.

Кому і навіщо це потрібно

Скрінрідером на телефоні користуються незрячі й слабкозорі люди, збільшеним шрифтом — люди старшого віку, керуванням перемикачами — люди з порушеннями моторики. Якщо кнопка «Оплатити» озвучується просто як «кнопка», людина не завершить покупку і не отримає послугу.

Для державних сервісів дотримання ДСТУ EN 301 549 уже обовʼязкове. Для бізнесу вимоги стануть обовʼязковими з ухваленням законопроєкту 14278, а компанії, що працюють на ринку ЄС, уже мають виконувати European Accessibility Act — він прямо поширюється на застосунки банків, інтернет-магазинів і транспорту.

Перед початком: як увімкнути засоби доступності

ЩоiOSAndroid
СкрінрідерПараметри → Доступність → 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 Guidelines44 × 44 pt
Android / Material Design48 × 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_testFlutterТести на розмір цілей, підписи й контраст тексту
VoiceOver і TalkBackобидвіГоловний інструмент: жоден автотест не замінить проходження екрана скрінрідером

Важливо: автоматичні перевірки знаходять лише частину проблем — переважно технічні (розмір, контраст, відсутній підпис). Логічність порядку фокуса, зрозумілість назв і те, чи можна взагалі пройти сценарій, перевіряє тільки людина. Детальніше про поєднання автоматичної й ручної перевірки — у статті Аудит доступності: що це і як проводять.

Особливості тестування мобільних застосунків на доступність

Чим тестування застосунку відрізняється від перевірки сайту:

  • Немає універсального сканера. Сайт можна просканувати за хвилину, застосунок — тільки пройти руками на пристрої.
  • Дві платформи — дві поведінки. Той самий екран на iOS і Android може озвучуватися по-різному, особливо на React Native і Flutter. Тестуйте на обох.
  • Кросплатформні фреймворки мають власну розмітку доступності: Semantics у Flutter, accessibilityLabel / accessibilityRole у React Native. Якщо її не задати, компонент буде «німим» на обох платформах.
  • Сценарії важливіші за екрани. Перевіряйте не окремі екрани, а шлях: вхід → пошук → оформлення → оплата. Одна недоступна кнопка посередині блокує весь сценарій.
  • Системні налаштування. Застосунок має поважати налаштування телефона (шрифт, рух, контраст) — це окрема вимога ДСТУ EN 301 549 для програмного забезпечення.

Як вбудувати перевірку в процес розробки

  1. Дизайн: контраст, розмір цілей і підписи іконок закладаються в макеті — виправляти в коді дорожче.
  2. Розробка: стандартні компоненти замість саморобних; назва для кожної іконки — частина definition of done.
  3. Автотести: увімкніть AccessibilityChecks (Android) і performAccessibilityAudit() (iOS) у наявних UI-тестах.
  4. Перед релізом: 15 хвилин на ключовий сценарій з VoiceOver і TalkBack за цим чек-листом.
  5. Після релізу: відгуки користувачів про доступність — окрема мітка в трекері.

Про те, як організувати такі перевірки в команді, — у статті Внутрішній аудит доступності для команд розробки.

Часті питання

Чи можна перевірити застосунок на доступність автоматично? Частково. 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. Заявка — на сторінці аудиту мобільних застосунків.

Не впевнені, що пройшли все? Надішліть посилання на застосунок у магазині й оберіть три екрани — ми перевіримо їх безкоштовно на реальних пристроях зі скрінрідерами.

Перевірити свій застосунок
Чи була ця стаття корисною?