Ошибки доступности в учебных материалах по React
В последние месяцы мы изучали множество проектов на основе React — от открытого исходного кода до клиентских работ и собственных старых проектов, которые лучше не вспоминать. Мы заметили закономерность: проблемы с доступностью повторяются снова и снова примерно в одинаковых пропорциях почти во всех кодовых базах.
Почему это происходит?
Проблемы возникают не потому что учебные материалы плохие; наоборот, руководства по React являются одними из лучших ресурсов для изучения веб-разработки. Однако у них есть ограничение: они должны укладываться в определённый формат — например, уложиться в 12 минут видео или 800 слов текста. И первое, что сокращается при ограничении времени или пространства, — это часть, где компонент должен корректно работать для пользователя, который не использует мышь.
Авторы обычно знают об этом и часто упоминают: «в продакшене вам нужно будет обработать Х», но затем переходят дальше. Читатели же копируют пример прямо в своё приложение и отправляют его в производство.
Таким образом, эта статья не о том, что учебники по React плохи, а о том, какие моменты пропускаются и как можно быстро исправить эти недочёты за дополнительные 30 секунд работы над кодом.
Распространённая ошибка №1: кликабельный div
Если одна модель определяет культуру обучения React, то это <div onClick={...}>. Она встречается повсюду, так как естественна в синтаксисе JSX. Вы уже пишете div для разметки, у вас уже есть обработчик события onClick, и результат выглядит правильно визуально. Стилизованный div с обработчиком событий практически неотличим от кнопки.
Однако для инструментов проверки доступности (axe-core), пользователей клавиатуры и программ экранного доступа он совершенно другой элемент. У элемента <div> нет роли, фокуса, активации клавишами Enter/Space и он не отображается в дереве доступности как интерактивный элемент.
Пользователь клавиатуры просто не сможет добраться до него.
Решение простое: замените <div> на кнопку или ссылку:
// До исправления
<div className="card" onClick={handleClick}>
Click me!
</div>
// После исправления
<button className="card" onClick={handleClick}>
Click me!
</button>
Это изменение займёт всего несколько секунд, но значительно улучшит доступность вашего приложения.