mobileaccessibilityregressioniosandroid

Accessibility-чек-лист для мобильного приложения в 2026

28 июня 2025 в EU вступил в силу European Accessibility Act. Для большинства b2c-приложений (банкинг, e-commerce, транспорт, билеты, медиа, ридеры) accessibility теперь не «хочется», а юридическое требование — со штрафами до миллиона евро в некоторых странах. В США давно работает ADA, а WCAG 2.1 AA де-факто стандарт во всём мире.

При этом во многих командах a11y-тестирование сводится к «дизайн сказал — мы согласовали». Этот чек-лист — что именно тестировать руками, чем автоматизировать, и какие 10 типов багов ловятся за пару часов на любом приложении.

1. Скринридеры: VoiceOver и TalkBack

Главный инструмент пользователя с нарушением зрения. Открыть приложение, закрыть глаза, попробовать выполнить ключевые сценарии — это не упражнение, это базовый прогон.

iOS — VoiceOver:

  • Settings → Accessibility → VoiceOver → On (или тройной клик по боковой кнопке как ярлык).
  • Swipe вправо/влево — переход по элементам. Double-tap — активация. Three-finger swipe — прокрутка.
  • Запустить экран чтения через Rotor (двумя пальцами крутить по экрану) — режим Headings, Links, Form Controls.

Android — TalkBack:

  • Settings → Accessibility → TalkBack → On (или зажать обе клавиши громкости как ярлык).
  • Swipe — переход по элементам. Double-tap — активация. Two-finger scroll.

Что проверять:

  • Порядок чтения соответствует визуальному порядку (не «корзина → товар → цена → название»).
  • Каждый интерактивный элемент произносится — кнопки без label звучат как «button button button» и пользователь не понимает, что нажимать.
  • Иконки имеют accessibilityLabel (iOS) или contentDescription (Android). Декоративные — помечены как hidden, чтобы скринридер их пропустил.
  • Скринридер не зачитывает то, что скрыто визуально (например, элементы за модалкой).
  • Кастомные компоненты имеют корректные accessibilityTraits / Role — слайдер ведёт себя как слайдер, чекбокс — как чекбокс.
  • При появлении ошибки в форме фокус переходит к ошибке, а не остаётся на «Отправить».

2. Dynamic Type и Font Scale

Пользователь со слабым зрением включает в системе крупный шрифт. Приложение, которое ломается на 200% — теряет этого пользователя.

Как включить:

  • iOS — Settings → Accessibility → Display & Text Size → Larger Text → ползунок до конца (AX5).
  • Android — Settings → Accessibility → Font size → максимум. Дополнительно Display size — увеличивает всё, включая иконки.

Что ломается:

  • Текст обрезается в кнопках («Подтвердит…» вместо «Подтвердить заказ»).
  • Текст налезает на соседние элементы.
  • Числа в табах и счётчиках уходят за пределы.
  • Высота строки фиксирована — текст обрезается сверху или снизу.
  • Layout сломан — кнопки не нажимаются, потому что overlapping.

Решение в коде — использовать платформенные текстовые стили (на iOS — UIFontMetrics / scaledFont(for:); на Android — sp единицы и ConstraintLayout с min/max). Тест — увеличить шрифт и пройти golden path.

3. Контрастность (WCAG AA / AAA)

Минимум по WCAG 2.1 AA — контраст текста к фону 4.5:1 (обычный) и 3:1 (крупный, от 18pt или 14pt bold). Для UI-элементов (бордеры кнопок, иконки) — 3:1.

Инструменты:

  • Xcode Accessibility Inspector (Xcode → Open Developer Tool → Accessibility Inspector) — пипетка по экрану, показывает контраст и подсвечивает проблемы.
  • Stark — плагин Figma и Sketch для проверки контраста на этапе дизайна (часто проще ловить там, чем в QA).
  • axe DevTools / Lighthouse — для веба, чек контраста встроен в audit.
  • Android Accessibility Scanner (приложение из Play Store) — сканирует экран и показывает все проблемы a11y, включая контраст.

Что часто проваливается:

  • Светло-серый placeholder в поле ввода (#CCCCCC на белом — контраст 1.6:1).
  • Disabled-состояние кнопок — серая на серой.
  • Иконки на градиентах и фото — контраст плавающий.
  • Цвет ссылки и обычного текста различается только оттенком (см. следующий пункт).

4. Цвет как единственный носитель информации

Дальтоники не различают красное и зелёное (~8% мужчин). Если статус заказа «зелёный кружок = доставлено / красный = отменён» без иконки или подписи — это баг доступности.

Тест-кейсы:

  • Скриншот приложения → конвертация в grayscale (или iOS Settings → Accessibility → Display & Text Size → Color Filters → Grayscale). Все ли состояния различимы?
  • Графики и диаграммы — каждый ряд имеет свой паттерн (точки, штриховка), а не только цвет.
  • Валидация форм — ошибка показана не только красной рамкой, но и текстом ошибки или иконкой.
  • Ссылки в тексте — подчёркнуты, а не только покрашены в синий.

5. Размеры touch target’ов

iOS HIG требует минимум 44×44pt для всех интерактивных элементов. Android Material — 48×48dp. WCAG 2.5.5 (AAA) — 44×44 CSS пикселя. См. Apple HIG: Accessibility.

Что часто проваливается:

  • Маленький «×» закрытия модалки в углу — 20×20pt.
  • Чекбоксы с tap-area = размеру самого чекбокса (надо расширять hitTest на 44pt).
  • Иконки в табах рядом — соседние можно случайно нажать.
  • Ссылки в тексте — высота строки 16pt, попасть пальцем сложно.

В Xcode проверка через Accessibility Inspector → Audit. В Android Studio — встроенный Layout Inspector + Accessibility Scanner.

6. Keyboard navigation и внешние клавиатуры

На iOS пользователи с Bluetooth-клавиатурой (включая Switch Control пользователей) ходят по интерфейсу через Tab. На Android аналогично. Веб — обязательная история.

Что проверять:

  • Все интерактивные элементы достижимы через Tab.
  • Порядок фокуса соответствует визуальному (сверху вниз, слева направо).
  • Фокус видим — есть выделение текущего элемента (рамка, подсветка).
  • В модалках фокус заперт внутри (focus trap) — Tab не уходит на элементы под модалкой.
  • Esc закрывает модалку, Enter активирует.

7. Reduce Motion, Reduce Transparency, Bold Text

Анимация может вызывать тошноту у пользователей с вестибулярными нарушениями. Прозрачность ухудшает читаемость. Все эти настройки приложение должно уважать.

Как включить:

  • iOS — Settings → Accessibility → Motion → Reduce Motion / Auto-Play Video Previews / Limit Frame Rate.
  • iOS — Settings → Accessibility → Display & Text Size → Reduce Transparency / Increase Contrast / Bold Text.
  • Android — Settings → Accessibility → Remove animations.

Что должно меняться:

  • Параллакс, авто-проигрывание видео в фидах, длинные fade/slide-анимации — отключаются или заменяются на cross-fade.
  • Полупрозрачные навбары и tab-бары — становятся непрозрачными.
  • Жирный текст — действительно применяется (часто игнорируется кастомными шрифтами).

8. Видео, аудио и мультимедиа

  • Видео имеет captions (subtitles) — обязательно. Если контент международный — на нескольких языках.
  • Captions включаются в плеере, не зашиты в видеоряд (иначе нельзя выключить или перевести).
  • Аудио-контент имеет transcript (расшифровку) или альтернативное текстовое описание.
  • Видео не автоплейится со звуком — у пользователя не должно «выстрелить» из тишины.
  • Анимированные изображения (GIF, Lottie) можно поставить на паузу.

9. Семантика и label-инг

Главная причина плохой работы скринридеров — отсутствующие или неинформативные labels.

iOS — основные свойства:

  • accessibilityLabel — что это («Кнопка избранное»).
  • accessibilityHint — что произойдёт при действии («Добавит в избранное»).
  • accessibilityValue — текущее значение (для слайдеров, чекбоксов).
  • accessibilityTraits — роль (.button, .selected, .header).

Android — основные свойства:

  • contentDescription — что это.
  • importantForAccessibility — скрыть декоративные элементы.
  • Custom views — задавать AccessibilityNodeInfo через делегата.

Антипаттерны:

  • Label = «image» или «button button».
  • Label дублирует hint («Кнопка избранное. Кнопка для избранного»).
  • Label содержит «нажмите чтобы» — скринридер сам говорит «дважды коснитесь, чтобы активировать».

10. Автотестирование a11y

Ручной прогон скринридером всегда обязателен, но базовые проверки — labels, контраст, touch targets, дубликаты ID — можно автоматизировать.

  • iOS — XCUITest accessibility audit: XCUIApplication().performAccessibilityAudit() (Xcode 15+). Прогоняет автоаудит и валит тест на найденных issue.
  • Android — Espresso AccessibilityChecks + Accessibility Test Framework. Включается одной строкой, проверяет каждое действие.
  • Webaxe-core, Lighthouse в CI. Не ловит всё, но даёт быстрый baseline.
  • Дизайн — Stark в Figma — отлавливает проблемы до того, как они попали в код.

Автотесты ловят ~30–40% реальных проблем (по данным Deque). Остальное — только ручное прохождение скринридером и реальные пользователи.

11. Финальный чек-лист

Минимум для регресса перед релизом:

  • Все ключевые экраны проходимы только VoiceOver / TalkBack без зрения.
  • На Dynamic Type / Font Scale 200% golden path не сломан.
  • Контраст текста ≥ 4.5:1 (для обычного), бордеров кнопок ≥ 3:1.
  • В grayscale различимы все состояния, валидация форм не зависит только от цвета.
  • Touch target’ы ≥ 44×44pt / 48×48dp.
  • Tab-навигация через внешнюю клавиатуру работает, фокус видим, в модалках trap.
  • Reduce Motion / Reduce Transparency / Bold Text приложением уважаются.
  • Видео имеет captions, никакого автоплея со звуком.
  • Иконки и кастомные контролы имеют корректные labels и traits.
  • В CI крутится автоаудит (XCUITest или Espresso).

Accessibility — это не «помочь нескольким людям». 15% населения живёт с какой-то формой инвалидности (WHO), плюс ситуативные нарушения у всех — солнце на экране, телефон одной рукой с кофе, наушники сели и нет captions. A11y — это про то, чтобы продукт работал у всех.