Приведите пример пользовательского интерфейса (HTML/React или Android XML/Jetpack Compose) с проблемой доступности (например, некорректные aria-атрибуты, отсутствие меток, плохой цветовой контраст) и опишите, как вы бы исправили интерфейс, какие инструменты автоматической проверки и ручного тестирования использовать, и как оценивать доступность для пользователей с разными нарушениями
Ниже — практический пример ReactReactReact с явной проблемой доступности, описание исправления, список автоматических инструментов и способы ручного тестирования, а также как оценивать интерфейс с точки зрения разных типов нарушений.
1) Проблемный пример React,JSXReact, JSXReact,JSX
Пример простого переключателя уведомлений с несколькими проблемами: использован div c role="switch" без поддержки клавиатуры и фокуса, плохой цветовой контраст текста, нет явной доступной подписи/aria-label, отсутствует видимый индикатор фокуса.
Проблемный код: function NotificationToggleon,setOn{ on, setOn }on,setOn { return ( <div className={toggle ${on ? 'on' : 'off'}} role="switch" aria-checked={on} onClick={() => setOn(!on)} // нет tabindex, нет обработки клавиш, нет aria-label
div с role="switch" требует явной поддержки клавиатуры Enter/SpaceEnter/SpaceEnter/Space и tabindex=0; иначе пользователи клавиатуры не смогут взаимодействовать.Поведение фокуса: браузер не показывает фокус для div, пользователь не знает, что элемент фокусируем.Цвет текста (#bdbdbd на белом) может не соответствовать требованиям контраста низкаячитаемостьдлялюдейснизкимзрениемнизкая читаемость для людей с низким зрениемнизкаячитаемостьдлялюдейснизкимзрением.Отсутствует aria-label/информативный текст для скринридеров внекоторыхслучаяхвизуальныйтекстможетнебытьправильноассоциированв некоторых случаях визуальный текст может не быть правильно ассоциированвнекоторыхслучаяхвизуальныйтекстможетнебытьправильноассоциирован.Если aria-checked не синхронизируется строкой/булевымстрокой/булевымстрокой/булевым, могут быть расхождения.
2) Исправленный вариант — лучший подход Лучше использовать семантически корректный элемент (input[type=checkbox] + label или button с role="switch") и обеспечить:
Вариант с button корректнореализованныйпереключателькорректно реализованный переключателькорректнореализованныйпереключатель: function NotificationToggleon,setOn{ on, setOn }on,setOn { const toggle = => setOn!on!on!on;
Цвет текста: использовать контраст >= 4.5:1 для обычного текста WCAGAAWCAG AAWCAGAA, либо >= 3:1 для большого текста.Добавить focus-visible outline/box−shadowoutline/box-shadowoutline/box−shadow для кнопки, чтобы при навигации с клавиатуры фокус был очевиден.Сделать целевую область не менее ~44x44 CSS-пикселей удобнодлясенсорноговводаимоторныхнарушенийудобно для сенсорного ввода и моторных нарушенийудобнодлясенсорноговводаимоторныхнарушений.
Альтернатива: использовать input[type="checkbox"] скрытый визуально и label, это обеспечивает нативную семантику и клавиатурное поведение «из коробки».
3) Советы по исправлениям сводносводносводно
Используйте семантические элементы button,input,abutton, input, abutton,input,a, а не div/span + role, если возможно.Если используете ARIA, соблюдайте спецификацию: корректные роли, aria-checked, aria-expanded и т.п. и синхронизируйте значения.Реализуйте полную клавиатурную навигацию: tabindex, обработчики клавиш Enter/Space/EscapeEnter/Space/EscapeEnter/Space/Escape, логичную последовательность фокуса и видимые индикаторы фокуса.Обеспечьте достаточный цветовой контраст и не используйте только цвет для передачи информации добавляйтетекст,иконки,паттерныдобавляйте текст, иконки, паттерныдобавляйтетекст,иконки,паттерны.Да, проверяйте фокус-ловушки в модальных окнах, aria-live для динамического контента.Всегда добавляйте понятные метки для форм: или aria-label/aria-labelledby.
4) Автоматические инструменты для проверки рекомендуетсяиспользоватьихвCIилокальнорекомендуется использовать их в CI и локальнорекомендуетсяиспользоватьихвCIилокально
axe-core / axe DevTools браузерноерасширение,библиотекадляCIбраузерное расширение, библиотека для CIбраузерноерасширение,библиотекадляCI — очень полезно для веба.eslint-plugin-jsx-a11y — линтер для React/JSX.Lighthouse вChromeDevToolsивCIв Chrome DevTools и в CIвChromeDevToolsивCI — показывает базовые A11y-проблемы.Accessibility Insights MicrosoftMicrosoftMicrosoft — инспекция + fast checks.WAVE webaccessibilityevaluationtoolweb accessibility evaluation toolwebaccessibilityevaluationtool — визуальная диагностика.pa11y / pa11y-ci — командная строка для автоматических проверок.jest-axe — для unit-тестов доступности.Контрастные проверщики: Contrast Checker, встроенный в devtools, плагин Stark для Figma/IDE.
5) Ручное тестирование обязательно;автоматическиеинструментынепоймутвсёобязательно; автоматические инструменты не поймут всёобязательно;автоматическиеинструментынепоймутвсё
Клавиатурная навигация: Переключение с Tab/Shift+Tab, взаимодействие с Enter/Space, проверка Esc для закрытия модалей.Убедиться, что порядок фокуса логичен, нет «потерянных» элементов.Видимый индикатор фокуса присутствует.Скринридеры: Windows: NVDA бесплатнобесплатнобесплатно + браузер Firefox/Chrome. JAWS — коммерческий.macOS: VoiceOver.Протестировать: корректность озвучивания меток, ролей, значений aria-*, правильность чтения заголовков/порядка.Масштабирование и увеличение: Увеличение страницы до 200% WCAGтестWCAG тестWCAGтест — элементы должны оставаться доступными и не ломать верстку.Цветовые нарушения: Использовать симуляторы дальтонизма, проверить, не зависит ли информация только от цвета.Сенсорные и моторные: Проверить размеры интерактивных зон, отсутствие мелких целей, время на ввод еслиестьограниченияповремени—предоставитьопцииесли есть ограничения по времени — предоставить опцииеслиестьограниченияповремени—предоставитьопции.Лайв-демонстрации динамики: Проверить aria-live, уведомления, смену контента: скринридер пользователя должен получать обновления.Тестирование с реальными пользователями наиболееценнонаиболее ценнонаиболееценно: Провести сеансы с людьми, использующими ассистивные технологии.
6) Как оценивать доступность для разных типов нарушений
Полная слепота используютскринридериспользуют скринридериспользуютскринридер: Показатели: корректные роли, aria-label/aria-labelledby, семантические теги header/main/nav/form/legendheader/main/nav/form/legendheader/main/nav/form/legend, логичное DOM-порядок, aria-live для динамики.Тесты: NVDA/VoiceOver чтение страницы, управление формами и компонентами, логика заголовков.Слабовидящие пользователи / люди пользующиеся экранным увеличением: Показатели: масштабируемость 200200%200, отзывчивая верстка, отсутствие фиксированных размеров, контраст >= 4.5:1 для текста.Тесты: масштабирование, тесты с высоким контрастом/тематикой ОС.Цветовая слепота: Показатели: информация не только по цвету добавитьтекст/иконки/паттерныдобавить текст/иконки/паттерныдобавитьтекст/иконки/паттерны, контраст между элементами и фоном.Тесты: симуляторы дальтонизма, отключение цветов.Моторные нарушения ограниченнаямобильностьограниченная мобильностьограниченнаямобильность: Показатели: крупные зоны нажатия, возможность навигации с клавиатуры, поддержка альтернативных способов ввода, больше времени для операций.Тесты: попытки взаимодействовать только клавиатурой, проверка размеров touch targets.Нарушения когнитивные: Показатели: простая и предсказуемая навигация, короткие инструкции, явные ошибки и подсказки, стабильно понятные лейблы.Тесты: читаемость, упрощение текста, проверка понятности ошибок и подсказок.
7) Критерии приемки примернопримернопримерно
WCAG 2.1 уровень AA: контраст ≥ 4.5:1 для обычного текста, все интерактивные элементы доступны с клавиатуры, формы имеют метки, динамические изменения озвучиваются/анонсируются.Нет критических ошибок, помеченных axe как "violation".Прохождение ручного тестирования с клавиатурой и скринридером ключевыесценарии:регистрация/вход/формы/модальныеокна/основнойпотокключевые сценарии: регистрация/вход/формы/модальные окна/основной потокключевыесценарии:регистрация/вход/формы/модальныеокна/основнойпоток.
8) Интеграция в процесс разработки
Линтинг eslint−plugin−jsx−a11yeslint-plugin-jsx-a11yeslint−plugin−jsx−a11y.Unit/E2E тесты на доступность jest−axe,cypress−axejest-axe, cypress-axejest−axe,cypress−axe.Автоматический отчет в CI axe/pa11y/LighthouseCIaxe/pa11y/Lighthouse CIaxe/pa11y/LighthouseCI — предотвратить регрессии.Регулярный ручной аудит перед релизом и тесты с реальными пользователями с инвалидностью.
Короткая контрольная карта checklistchecklistchecklist для интерфейса:
Семантика: теги и роли используются корректно.Метки: все поля и интерактивные элементы имеют понятные подписи.Клавиатура: все функции доступны с клавиатуры; видимый фокус.Контраст: текст и UI соответствуют порогам WCAG.Динамика: aria-live и уведомления работают корректно.Формы: ошибки доступны и объяснены.Модали/диалоги: фокус захватывается и возвращается после закрытия.Тестирование: запущены автоматические проверки и выполнены ручные тесты со скринридером.
Если хотите, могу:
Привести исправленный пример с inputtype=checkboxtype=checkboxtype=checkbox и полной стилизацией + CSS фон,размеры,focus−visibleфон, размеры, focus-visibleфон,размеры,focus−visible.Показать примеры конфигурации axe/pa11y в CI или пример теста с jest-axe.Подготовить чек-лист для ручного тестирования в виде файла PDF/MDPDF/MDPDF/MD.
Ниже — практический пример ReactReactReact с явной проблемой доступности, описание исправления, список автоматических инструментов и способы ручного тестирования, а также как оценивать интерфейс с точки зрения разных типов нарушений.
1) Проблемный пример React,JSXReact, JSXReact,JSX Пример простого переключателя уведомлений с несколькими проблемами: использован div c role="switch" без поддержки клавиатуры и фокуса, плохой цветовой контраст текста, нет явной доступной подписи/aria-label, отсутствует видимый индикатор фокуса.
Проблемный код:
function NotificationToggleon,setOn{ on, setOn }on,setOn {
return (
<div
className={toggle ${on ? 'on' : 'off'}}
role="switch"
aria-checked={on}
onClick={() => setOn(!on)}
// нет tabindex, нет обработки клавиш, нет aria-label
<span className="label" style={{ color: '#bdbdbd' }}>
Notifications
);
}
Почему это плохо:
div с role="switch" требует явной поддержки клавиатуры Enter/SpaceEnter/SpaceEnter/Space и tabindex=0; иначе пользователи клавиатуры не смогут взаимодействовать.Поведение фокуса: браузер не показывает фокус для div, пользователь не знает, что элемент фокусируем.Цвет текста (#bdbdbd на белом) может не соответствовать требованиям контраста низкаячитаемостьдлялюдейснизкимзрениемнизкая читаемость для людей с низким зрениемнизкаячитаемостьдлялюдейснизкимзрением.Отсутствует aria-label/информативный текст для скринридеров внекоторыхслучаяхвизуальныйтекстможетнебытьправильноассоциированв некоторых случаях визуальный текст может не быть правильно ассоциированвнекоторыхслучаяхвизуальныйтекстможетнебытьправильноассоциирован.Если aria-checked не синхронизируется строкой/булевымстрокой/булевымстрокой/булевым, могут быть расхождения.2) Исправленный вариант — лучший подход
клавиатурную доступность Enter/SpaceEnter/SpaceEnter/Space,видимый фокус,адекватный контраст,корректные ARIA-атрибуты и/или метки.Лучше использовать семантически корректный элемент (input[type=checkbox] + label или button с role="switch") и обеспечить:
Вариант с button корректнореализованныйпереключателькорректно реализованный переключателькорректнореализованныйпереключатель:
function NotificationToggleon,setOn{ on, setOn }on,setOn {
const toggle = => setOn!on!on!on;
return (
<button
type="button"
role="switch"
aria-checked={on}
onClick={toggle}
onKeyDown={(e) => {
if (e.key === ' ' || e.key === 'Enter') {
e.preventDefault();
toggle();
}
}}
aria-label="Включить уведомления"
className={toggle-button ${on ? 'on' : 'off'}}
// CSS должен обеспечить видимый фокус и хороший контраст
Уведомления );
}
CSS-заметки:
Цвет текста: использовать контраст >= 4.5:1 для обычного текста WCAGAAWCAG AAWCAGAA, либо >= 3:1 для большого текста.Добавить focus-visible outline/box−shadowoutline/box-shadowoutline/box−shadow для кнопки, чтобы при навигации с клавиатуры фокус был очевиден.Сделать целевую область не менее ~44x44 CSS-пикселей удобнодлясенсорноговводаимоторныхнарушенийудобно для сенсорного ввода и моторных нарушенийудобнодлясенсорноговводаимоторныхнарушений.Альтернатива: использовать input[type="checkbox"] скрытый визуально и label, это обеспечивает нативную семантику и клавиатурное поведение «из коробки».
3) Советы по исправлениям сводносводносводно
Используйте семантические элементы button,input,abutton, input, abutton,input,a, а не div/span + role, если возможно.Если используете ARIA, соблюдайте спецификацию: корректные роли, aria-checked, aria-expanded и т.п. и синхронизируйте значения.Реализуйте полную клавиатурную навигацию: tabindex, обработчики клавиш Enter/Space/EscapeEnter/Space/EscapeEnter/Space/Escape, логичную последовательность фокуса и видимые индикаторы фокуса.Обеспечьте достаточный цветовой контраст и не используйте только цвет для передачи информации добавляйтетекст,иконки,паттерныдобавляйте текст, иконки, паттерныдобавляйтетекст,иконки,паттерны.Да, проверяйте фокус-ловушки в модальных окнах, aria-live для динамического контента.Всегда добавляйте понятные метки для форм: или aria-label/aria-labelledby.4) Автоматические инструменты для проверки рекомендуетсяиспользоватьихвCIилокальнорекомендуется использовать их в CI и локальнорекомендуетсяиспользоватьихвCIилокально
axe-core / axe DevTools браузерноерасширение,библиотекадляCIбраузерное расширение, библиотека для CIбраузерноерасширение,библиотекадляCI — очень полезно для веба.eslint-plugin-jsx-a11y — линтер для React/JSX.Lighthouse вChromeDevToolsивCIв Chrome DevTools и в CIвChromeDevToolsивCI — показывает базовые A11y-проблемы.Accessibility Insights MicrosoftMicrosoftMicrosoft — инспекция + fast checks.WAVE webaccessibilityevaluationtoolweb accessibility evaluation toolwebaccessibilityevaluationtool — визуальная диагностика.pa11y / pa11y-ci — командная строка для автоматических проверок.jest-axe — для unit-тестов доступности.Контрастные проверщики: Contrast Checker, встроенный в devtools, плагин Stark для Figma/IDE.5) Ручное тестирование обязательно;автоматическиеинструментынепоймутвсёобязательно; автоматические инструменты не поймут всёобязательно;автоматическиеинструментынепоймутвсё
Клавиатурная навигация:Переключение с Tab/Shift+Tab, взаимодействие с Enter/Space, проверка Esc для закрытия модалей.Убедиться, что порядок фокуса логичен, нет «потерянных» элементов.Видимый индикатор фокуса присутствует.Скринридеры:
Windows: NVDA бесплатнобесплатнобесплатно + браузер Firefox/Chrome. JAWS — коммерческий.macOS: VoiceOver.Протестировать: корректность озвучивания меток, ролей, значений aria-*, правильность чтения заголовков/порядка.Масштабирование и увеличение:
Увеличение страницы до 200% WCAGтестWCAG тестWCAGтест — элементы должны оставаться доступными и не ломать верстку.Цветовые нарушения:
Использовать симуляторы дальтонизма, проверить, не зависит ли информация только от цвета.Сенсорные и моторные:
Проверить размеры интерактивных зон, отсутствие мелких целей, время на ввод еслиестьограниченияповремени—предоставитьопцииесли есть ограничения по времени — предоставить опцииеслиестьограниченияповремени—предоставитьопции.Лайв-демонстрации динамики:
Проверить aria-live, уведомления, смену контента: скринридер пользователя должен получать обновления.Тестирование с реальными пользователями наиболееценнонаиболее ценнонаиболееценно:
Провести сеансы с людьми, использующими ассистивные технологии.
6) Как оценивать доступность для разных типов нарушений
Полная слепота используютскринридериспользуют скринридериспользуютскринридер:Показатели: корректные роли, aria-label/aria-labelledby, семантические теги header/main/nav/form/legendheader/main/nav/form/legendheader/main/nav/form/legend, логичное DOM-порядок, aria-live для динамики.Тесты: NVDA/VoiceOver чтение страницы, управление формами и компонентами, логика заголовков.Слабовидящие пользователи / люди пользующиеся экранным увеличением:
Показатели: масштабируемость 200200%200, отзывчивая верстка, отсутствие фиксированных размеров, контраст >= 4.5:1 для текста.Тесты: масштабирование, тесты с высоким контрастом/тематикой ОС.Цветовая слепота:
Показатели: информация не только по цвету добавитьтекст/иконки/паттерныдобавить текст/иконки/паттерныдобавитьтекст/иконки/паттерны, контраст между элементами и фоном.Тесты: симуляторы дальтонизма, отключение цветов.Моторные нарушения ограниченнаямобильностьограниченная мобильностьограниченнаямобильность:
Показатели: крупные зоны нажатия, возможность навигации с клавиатуры, поддержка альтернативных способов ввода, больше времени для операций.Тесты: попытки взаимодействовать только клавиатурой, проверка размеров touch targets.Нарушения когнитивные:
Показатели: простая и предсказуемая навигация, короткие инструкции, явные ошибки и подсказки, стабильно понятные лейблы.Тесты: читаемость, упрощение текста, проверка понятности ошибок и подсказок.
7) Критерии приемки примернопримернопримерно
WCAG 2.1 уровень AA: контраст ≥ 4.5:1 для обычного текста, все интерактивные элементы доступны с клавиатуры, формы имеют метки, динамические изменения озвучиваются/анонсируются.Нет критических ошибок, помеченных axe как "violation".Прохождение ручного тестирования с клавиатурой и скринридером ключевыесценарии:регистрация/вход/формы/модальныеокна/основнойпотокключевые сценарии: регистрация/вход/формы/модальные окна/основной потокключевыесценарии:регистрация/вход/формы/модальныеокна/основнойпоток.8) Интеграция в процесс разработки
Линтинг eslint−plugin−jsx−a11yeslint-plugin-jsx-a11yeslint−plugin−jsx−a11y.Unit/E2E тесты на доступность jest−axe,cypress−axejest-axe, cypress-axejest−axe,cypress−axe.Автоматический отчет в CI axe/pa11y/LighthouseCIaxe/pa11y/Lighthouse CIaxe/pa11y/LighthouseCI — предотвратить регрессии.Регулярный ручной аудит перед релизом и тесты с реальными пользователями с инвалидностью.Короткая контрольная карта checklistchecklistchecklist для интерфейса:
Семантика: теги и роли используются корректно.Метки: все поля и интерактивные элементы имеют понятные подписи.Клавиатура: все функции доступны с клавиатуры; видимый фокус.Контраст: текст и UI соответствуют порогам WCAG.Динамика: aria-live и уведомления работают корректно.Формы: ошибки доступны и объяснены.Модали/диалоги: фокус захватывается и возвращается после закрытия.Тестирование: запущены автоматические проверки и выполнены ручные тесты со скринридером.Если хотите, могу:
Привести исправленный пример с inputtype=checkboxtype=checkboxtype=checkbox и полной стилизацией + CSS фон,размеры,focus−visibleфон, размеры, focus-visibleфон,размеры,focus−visible.Показать примеры конфигурации axe/pa11y в CI или пример теста с jest-axe.Подготовить чек-лист для ручного тестирования в виде файла PDF/MDPDF/MDPDF/MD.Какая из этих доработок полезнее вам сейчас?