Кому нужна доступность

Разбираемся, кто на самом деле пользуется доступным интерфейсом — и почему этот список гораздо шире, чем «незрячие люди со скринридером».

Веб-доступность (accessibility, сокращённо a11y — между «a» и «y» в слове одиннадцать букв) — свойство продукта, при котором человек может воспринять содержимое и выполнить задачу независимо от того, видит ли он экран, держит ли мышь и слышит ли звук.

Спросите пятерых фронтендеров, для кого нужна доступность. Четверо ответят: «для слепых, чтобы скринридер читал alt». Это правда — и примерно десятая часть правды. Из-за такой картины мира доступность в голове разработчика превращается в благотворительную нагрузку ради редкого пользователя, которого он никогда не видел в аналитике. А потом выясняется, что оформить заказ не может менеджер по продажам с трекпадом, у которого сломана правая рука, и что кнопка «Оплатить» невидима на солнце.

Поэтому договоримся на берегу: доступность — это не режим сострадания, а обычная характеристика качества интерфейса. Такая же, как скорость загрузки или отсутствие багов в корзине. Разберёмся, кто именно платит за её отсутствие.

Настоящий состав аудитории

Клавиатурные пользователи

Самая большая и самая невидимая группа. Мышью не пользуются не только из-за тремора, туннельного синдрома, ДЦП или ампутации. Ей не пользуются ещё и потому, что клавиатурой быстрее: любой человек, заполняющий по сорок форм в день, ходит по полям через Tab, а не тянется к мыши.

Классический способ сломать сайт для них — сделать кнопку не кнопкой:

<!-- Работает только мышью: с клавиатуры сюда невозможно попасть -->
<div class="btn" onclick="addToCart(42)">В корзину</div>

Мышью — работает. С клавиатуры — недостижимо: <div> не попадает в порядок обхода по Tab и не реагирует на Enter. Правильный вариант — одна строка:

<button type="button" class="btn" onclick="addToCart(42)">В корзину</button>

Три быстрых признака, что сайт для клавиатурного пользователя наполовину сломан: фокус не видно, порядок обхода прыгает из подвала в шапку, модальное окно не закрывается по Esc и не отпускает фокус.

Слабовидящие

По оценкам ВОЗ, с нарушениями зрения в мире живёт больше двух миллиардов человек, и подавляющее большинство — не незрячие, а именно слабовидящие. Скринридер они, как правило, не включают. Они увеличивают масштаб страницы до 200–400 %, ставят крупный системный шрифт, включают тёмную тему, приближают экран.

Что у них ломается: жёстко заданные высоты блоков (текст вылезает и обрезается), «липкие» шапка и баннер о cookie, которые на 300 % занимают весь экран, текст, зашитый в картинку, и горизонтальная прокрутка, появляющаяся при увеличении.

Дальтонизм и цветовосприятие

Красно-зелёная цветовая слепота встречается примерно у 8 % мужчин и 0,5 % женщин европейского происхождения. Это каждый двенадцатый мужчина в вашей аудитории. Главная ошибка — передавать смысл одним лишь цветом: «поля с ошибкой подсвечены красным», «выполненные задачи зелёные».

<!-- Плохо: об ошибке говорит только красная рамка (класс input--error) -->
<input class="input input--error" name="phone">

<!-- Хорошо: цвет + текст + программная связь поля с сообщением -->
<label for="phone">Телефон</label>
<input id="phone" name="phone" class="input input--error"
       aria-invalid="true" aria-describedby="phone-err">
<p id="phone-err">Ошибка: введите телефон в формате +7 900 000-00-00</p>

Заодно это помогает всем: сообщение «Ошибка: введите телефон в формате…» полезнее красной рамки для любого человека, включая зрячего и торопящегося.

Моторные нарушения

Тремор, рассеянный склероз, последствия инсульта, обычная усталость к вечеру. Такому пользователю больно попадать в крестик закрытия размером 12×12 и невозможно пройти по выпадающему меню, которое раскрывается по наведению и схлопывается от малейшего увода курсора. Не случайно WCAG 2.2 добавил критерий 2.5.8 Target Size: минимальный интерактивный элемент — 24×24 CSS-пикселя (а практика мобильных гайдлайнов советует 44×44).

Слух

Видеоинструкция без субтитров и подкаст без расшифровки просто не существуют для глухого и слабослышащего человека. И для того, кто смотрит ваш ролик в метро без наушников, — тоже.

Когнитивные особенности

Дислексия, СДВГ, тревожность, возрастные изменения памяти. Их «ломают» форма, стирающая введённые данные при ошибке валидации, таймер сессии на три минуты без предупреждения, капча с искажёнными буквами и текст, набранный светло-серым по белому.

Постоянное, временное, ситуативное

У Microsoft есть удобная модель «спектра ограничений». Она снимает главное возражение «у нас таких пользователей нет».

КаналПостоянноеВременноеСитуативное
Зрениенезрячий человекрасширенные зрачки после приёма у офтальмологасолнце бьёт в экран телефона
Слухглухотаотитшумный вагон метро, забыли наушники
Движениеампутация рукирука в гипседержит ребёнка, свободна одна рука
ВниманиеСДВГтретья бессонная ночьзаполняет форму на бегу, между встречами

Людей с постоянными ограничениями в каждой строке немного. С ситуативными — все мы, регулярно. Кнопка размером с палец нужна не только человеку с тремором, но и вам в трясущемся автобусе. Контраст 4.5:1 нужен не только слабовидящему, но и вам на веранде в июле.

Почему доступность — это ещё и SEO, и просто удобство

Здесь работает не совпадение, а общая причина. У скринридера и у поискового робота один и тот же вход: семантическая разметка. Ни тот, ни другой не видит «синий прямоугольник с тенью и скруглением» — оба читают дерево тегов и пытаются понять смысл.

  • Заголовки h1h3 в правильном порядке — для скринридера это оглавление, по которому можно прыгать; для поисковика — структура документа.
  • Осмысленный alt — и озвучка картинки, и индексация в поиске по изображениям.
  • Текст ссылки «Условия доставки» вместо «Подробнее» — и понятный список ссылок в скринридере, и внятный анкор для поисковика.
  • Транскрипт видео — и доступ для глухих, и килобайты индексируемого текста там, где раньше был непрозрачный <video>.
  • Отсутствие горизонтальной прокрутки при увеличении — и слабовидящий, и мобильные метрики качества.

Масштаб проблемы легко проверить: ежегодный отчёт WebAIM Million, который автоматически сканирует миллион главных страниц, из года в год находит нарушения примерно на 95 % из них. Топ причин стабилен: низкий контраст текста, отсутствующий alt, пустые ссылки и кнопки, поля без подписей. Ни одна из этих проблем не требует ни редизайна, ни бюджета — только внимания на этапе вёрстки.

Как это работает

Чтобы понять, почему тег важнее любых ухищрений, нужно знать про дерево доступности (accessibility tree). Параллельно с DOM браузер строит второе дерево — упрощённое, для вспомогательных технологий. У каждого узла в нём есть четыре вещи: роль (что это — кнопка, ссылка, заголовок), имя (как это назвать вслух), состояние (нажата, раскрыта, отключена) и значение. Скринридер, голосовое управление и брайлевский дисплей читают именно это дерево, а не ваш CSS.

Тег <button>Купить</button> попадает туда как «роль: кнопка, имя: Купить» — бесплатно, вместе с фокусируемостью, реакцией на Enter и Пробел и правильным курсором. А <div class="btn">Купить</div> — как безымянный текстовый узел. Вот сколько кода нужно, чтобы вручную вернуть <div> то, что у <button> есть из коробки:

<div class="btn"
     role="button"
     tabindex="0"
     onclick="addToCart(42)"
     onkeydown="if (event.key === 'Enter' || event.key === ' ') { event.preventDefault(); addToCart(42); }">
  В корзину
</div>

Пять атрибутов, ручная обработка двух клавиш — и всё это только чтобы сравняться с нативным тегом, который к тому же сам умеет работать внутри <form> и правильно ведёт себя в режиме высокой контрастности. Отсюда главное практическое правило курса: доступность процентов на восемьдесят — это не «навесить ARIA», а «взять правильный тег».

Частые ошибки

  • «У нас таких пользователей нет». Их и не будет видно: скринридер не передаёт заголовок «я скринридер», а человек, который не смог оформить заказ, просто уходит и в отчёте выглядит как обычный отказ.
  • alt на всё подряд. Декоративные иконки должны иметь пустой alt="", иначе скринридер сорок раз за страницу зачитает «изображение icon-arrow-right».
  • Доступность как этап приёмки. Найти проблему в макете стоит минуты, в свёрстанном компоненте — часы, в дизайн-системе на проде — недели.
  • Отдельная «версия для слабовидящих» (та самая кнопка с глазиком). Почти всегда это урезанная копия, которую забывают обновлять. Нужен один сайт, который умеет масштабироваться и работать с клавиатуры.
  • Оверлеи — виджеты, обещающие «доступность в одну строчку скрипта». Они не чинят дерево доступности: <div> не станет кнопкой оттого, что поверх него подключили внешний скрипт. Сообщество пользователей скринридеров относится к таким виджетам резко отрицательно.

Итоги

  • Доступность — характеристика качества интерфейса, а не отдельный «режим для инвалидов».
  • Аудитория шире, чем кажется: клавиатурные пользователи, слабовидящие (их сильно больше, чем незрячих), дальтоники, люди с моторными и когнитивными особенностями.
  • Ограничения бывают постоянными, временными и ситуативными — в последнюю категорию попадает каждый из нас.
  • Скринридер и поисковый робот питаются одним и тем же: семантической разметкой. Поэтому доступность и SEO тянут в одну сторону.
  • Браузер строит дерево доступности с ролью, именем и состоянием каждого узла. Правильный тег даёт всё это бесплатно.
Проверьте себя
1. Какая группа пользователей чаще всего страдает от того, что кнопка сделана через <div> с обработчиком onclick?
AНезрячие пользователи скринридеров — и только они
BВсе, кто управляет страницей с клавиатуры: до такого элемента нельзя дойти по Tab и нажать Enter
CДальтоники: они не различают цвет кнопки
DНикто: браузер сам делает такой div фокусируемым
2. Почему доступность обычно улучшает и SEO?
AПоисковики поднимают в выдаче сайты с иконкой доступности
BСкринридер и поисковый робот читают одно и то же — семантическую разметку: заголовки, alt, осмысленные тексты ссылок
CДоступные сайты весят меньше, поэтому загружаются быстрее
DЭто совпадение, прямой связи нет