Всё про доступность интерфейсов
7 subscribers
116 photos
193 links
Download Telegram
Когда модальное окно видно, но для скринридера оно не окно

В IBM mcp-context-forge нашёлся хороший недельный кейс по доступности: большой epic по WCAG 2.1 AA уже открыт, но самая полезная точка входа — не «чинить всё», а поправить общие UI-хелперы, через которые повторяются одни и те же ошибки.

Что было проблемой: модалки в Admin UI открывались визуально, но общий helper не добавлял им роль dialog, не связывал окно с заголовком, не переводил фокус внутрь и не возвращал его обратно на кнопку открытия. Для клавиатуры и скринридера это легко превращается в ситуацию: интерфейс изменился, а пользователь не понимает, где он сейчас.

Вторая часть — ошибки в формах. Текст ошибки появлялся на экране, но поле не получало нормальную программную связь с этим текстом. Скринридер мог не прочитать, что именно не так и как это относится к текущему полю.

Что изменил в PR: общий modal-helper теперь выставляет dialog-семантику, aria-modal, подпись через заголовок, переводит фокус в окно и восстанавливает его после закрытия. Генерируемая copyable-modal тоже стала полноценным подписанным dialog. Валидация форм теперь ставит aria-invalid и связывает поле с текстом ошибки через aria-describedby; подсказки, которые уже были у поля, не затираются.

Это не «закрыли весь WCAG». Это нормальный маленький слой инфраструктуры: одна правка в общих помощниках улучшает сразу несколько будущих и существующих сценариев.

Кейс собран через Accessibility Auditor Skill.

Issue: IBM/mcp-context-forge #2274
PR: #5331
NVDA должен видеть не только ответ, но и ввод

В Command Code пользователь описал баг AI CLI: он печатает запрос, а экранный диктор не читает символы и текущую строку.

Для незрячего разработчика это ломает базовую безопасность: нельзя нормально проверить команду, путь к файлу или текст запроса до отправки.
Когда консоль «текстовая», но экранный доступ всё равно теряет ввод

В Command Code issue #509 пользователь с NVDA на Windows описал неприятную вещь: он печатает запрос в AI CLI, а экранный диктор не видит символы. Не читает текущую строку, не проговаривает буквы при движении стрелками, не даёт проверить уже набранный текст.

Это важная деталь именно для консольных AI-инструментов. Снаружи кажется: «ну это же текст, значит всё доступно». Но для незрячего разработчика доступность здесь не заканчивается на выводе ответа. Нужно ещё набрать запрос, перечитать его, поправить слово, проверить команду или путь к файлу до отправки.

Автор прямо пишет, что Claude Code раньше имел похожую проблему и её исправили. То есть это не абстрактная просьба «сделайте доступность», а конкретный рабочий сценарий: ввод в командной строке должен быть видим для NVDA так же надёжно, как обычное поле ввода.

Для команд вывод простой: если вы делаете терминальный интерфейс, проверяйте не только красивые ответы модели. Пройдите весь путь с NVDA или другим экранным диктором: набор текста, стрелки в строке, удаление, вставку, историю команд, подтверждение перед запуском. Иначе «просто текстовый интерфейс» может оказаться интерфейсом, где человек не может безопасно написать сам запрос.
В Nextcloud Talk для Android появился баг: TalkBack озвучивает время и статус сообщения, но не сам текст. Для мессенджера это ломает не «удобство», а сам разговор.
В чате главное - текст сообщения

В Nextcloud Talk для Android открыли простой, но неприятный баг: TalkBack и Select to Speak не читают текст сообщения.

По отчёту, проблема воспроизводится в Nextcloud Talk 24.0.1 на Android 12 и 14, на Xiaomi Redmi Note 9 и Motorola Moto G23. TalkBack озвучивает время и статус сообщения, а Select to Speak говорит, что в выбранной области нечего читать. То есть пользователь может понять, что элемент в чате есть, но не получить главное - саму фразу собеседника.

Для мессенджера это не косметика. Если экранный доступ читает обвязку сообщения, но пропускает тело, человек не может нормально вести разговор, проверить ответ, понять контекст и решить, что делать дальше. Интерфейс визуально живой, но смысловой слой чата для него фактически исчезает.

Командам здесь стоит проверять не один `contentDescription` и не общий фокус на строке, а реальный диалог с TalkBack: читается ли автор, текст сообщения, время, статус доставки, порядок этих данных и действия рядом с сообщением. И отдельно проверить Select to Speak: это другой пользовательский путь со своим поведением.
Markdown должен читаться целиком

Свежий баг в react-native-enriched-markdown: iOS VoiceOver пропускает обычные абзацы и жирный текст, хотя на Android TalkBack сценарий работает. Если через markdown идут инструкции или справка, это ломает не оформление, а доступ к содержанию.
Когда VoiceOver пропускает текст, это уже не «мелочь в markdown»

В react-native-enriched-markdown открыли свежий баг: на iOS VoiceOver не выбирает обычные абзацы и жирный текст. Автор приложил минимальный пример: заголовок, несколько абзацев, список, ссылка и выделенный текст. На Android с TalkBack этот же сценарий работает, а на iOS VoiceOver читает не всё.

Почему это важно: markdown часто используют не для украшения. Через него показывают инструкции, справки, правила, описания заказов, юридический текст, подсказки в приложении. Если экранный доступ видит ссылку, но пропускает соседний абзац или выделенный фрагмент, незрячий пользователь получает куски документа вместо документа.

В этом репозитории уже были старые исправления по VoiceOver: навигация по смысловым блокам, ссылки внутри абзацев, точность фокуса. Поэтому новый issue особенно показательный. Доступность rich text нельзя проверить один раз и забыть. После изменений в рендеринге, выборе текста, ссылках, списках и нативных слоях нужно снова пройтись экранным доступом.

Я бы проверял такие компоненты не только по «ссылка нажимается». Минимальный тест: обычный абзац читается целиком, заголовок объявляется как заголовок, список идёт пунктами, ссылка остаётся отдельным действием, выделенный текст не исчезает, а порядок чтения совпадает с тем, что видит зрячий пользователь.

Если приложение показывает важный текст через markdown, экранный доступ должен читать сам текст, а не случайно выбранные интерактивные островки.
Скрытый select тоже может мешать

В NetBox после аудита нашли неприятную вещь: скрытые нативные <select> за стилизованными выпадающими списками всё ещё попадают в дерево доступности.

Для JAWS это превращается в лишний listbox перед реальным combobox. На форме фильтров такой «призрак» сбивает понимание: где настоящее поле, что выбрано и куда попал фокус.

Полный разбор ниже.
Скрытый select тоже может мешать

В NetBox после аудита завели свежую задачу: в форме фильтров скрытые нативные <select>, которые стоят за стилизованными выпадающими списками, всё ещё попадают в дерево доступности.

Для зрячего пользователя это выглядит как обычный красивый комбобокс. А JAWS при проходе по форме слышит лишний listbox, потом combobox, причём скрытый элемент ещё и без понятного имени. На длинной форме фильтров такой шум мешает: человек начинает сомневаться, где реальное поле, что сейчас выбрано и куда вообще попал фокус.

Рядом в том же аудите есть похожая проблема: у Saved Filter не озвучивается подпись, вероятно из-за дублей id и сломанной связи label → control. Вместе это хорошо показывает один класс ошибок: визуальная замена стандартного элемента не должна оставлять за собой «призрак» старого элемента для экранного доступа.

Что я бы проверял в таких местах: после инициализации Select2, Tom Select или любого своего комбобокса пройти форму с экранным диктором и инспектором доступности. В дереве должен остаться один понятный контрол: с именем, ролью, текущим значением и нормальным состоянием. Всё техническое, что больше не служит пользовательским полем, нужно убрать из дерева доступности или корректно скрыть.

Источник: NetBox issue #22530, смежная задача: #22531.
Календарь открылся - и NVDA начал читать всё подряд

В react-datepicker выбор диапазона дат внутри всплывающего окна привёл к странному эффекту: NVDA сразу зачитал все выбранные дни в случайном порядке.

Это не мелкая «болтливость» экранного диктора. Если календарь при открытии вываливает поток дат, пользователь ещё до выбора теряет контекст: где фокус, какой день активен и что делать дальше.
Календарь открылся - и NVDA начал читать всё подряд

В react-datepicker появился хороший пример неочевидной ошибки в календарях. Пользователь открыл выбор диапазона дат внутри всплывающего окна, а NVDA сразу начал зачитывать все выбранные дни в случайном порядке: 6 июня, 7 июня, 9 июня, потом 8 июня, потом снова дальше по сетке.

Фокус при этом мог стоять вообще не на календаре, а на другом элементе окна. Но для NVDA открылся диалог, он вошёл в режим чтения и прошёлся по содержимому. Календарь уже отрисовал много ячеек с aria-selected="true", поэтому пользователь получил поток дат вместо понятного состояния.

Почему это мешает: человек ещё не начал выбирать дату, а интерфейс уже нагружает его шумом. В календаре это особенно неприятно - нужно держать в голове дни, диапазон, текущий фокус и следующий шаг. Если экранный доступ читает выбранные даты не по порядку, доверять такому контролу трудно.

Вывод для команд простой: календарь надо проверять не только по стрелкам внутри сетки. Откройте его как реальный пользователь: из кнопки, поля, всплывающего окна, модального слоя. Послушайте, что NVDA или другой экранный диктор говорит в первые секунды после открытия.

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

В Parla, нативном GNOME-клиенте для Delta Chat, пользователь описал простую проблему: списки чатов и сообщений открывают нужные действия только правой кнопкой мыши. С клавиатуры меню не вызывается.

Ожидаемый путь знакомый: Shift+F10 или клавиша контекстного меню. Но в списке чатов эти клавиши почему-то открывают меню поля ввода, а в списке сообщений не делают ничего. Для человека без мыши это уже не «неудобство», а закрытая часть продукта: действия над чатом или сообщением есть на экране, но до них нельзя добраться.

Это задевает не только «клавиатурных» пользователей. Для многих пользователей экранного доступа клавиатура - основной способ дойти до элемента, понять, где фокус, и вызвать доступные действия.

Хорошая проверка здесь очень бытовая: поставить фокус на строку списка и попробовать открыть все те же действия без мыши. Если контекстное меню существует только для правого клика, значит команда протестировала видимый интерфейс, но не протестировала управление.

Источник: trufae/parla#40
VPN должен быть доступен без мыши

Свежий issue по AmneziaVPN: NVDA и TalkBack спотыкаются не только о подписи кнопок, а о весь путь управления VPN - серверы, вкладки, удаление профиля и split tunneling.
VPN должен быть доступен без мыши

В AmneziaVPN появился свежий issue про доступность основных экранов для NVDA на Windows и TalkBack на Android.

Проблема не в одном забытом ярлыке. В отчёте перечислены сразу рабочие места, где незрячий пользователь теряет самостоятельность: выбор сервера, кнопки рядом с серверными настройками, нижние и верхние вкладки, удаление сервера, раздел split tunneling.

Особенно показателен Android-кейс: поле поиска приложений в split tunneling озвучивается как чувствительное или парольное, поэтому TalkBack не читает введённый текст нормально. А чекбоксы, по описанию автора, не включаются обычным жестом TalkBack - вместо двойного касания приходится удерживать элемент.

Для VPN это не косметика. Если человек не может быстро выбрать сервер, удалить сломанный профиль или настроить split tunneling без помощи зрячего, он фактически не контролирует инструмент, который должен давать безопасность и независимость.

Вывод для команд простой: проверять нужно не только главный Connect. Пройдите весь путь с клавиатурой и экранным доступом: вкладки, выбор сервера, соседние кнопки действий, удаление, поиск, чекбоксы, состояния включено/выключено. У каждого интерактивного элемента должны быть понятные имя, роль, состояние и нормальная активация.

Источник: issue amnezia-vpn/amnezia-client#2778. Рядом открыт PR с правками доступности, но финальную проверку всё равно надо делать в реальной сборке с NVDA и TalkBack.
Когда окно «не модальное», оно не должно вести себя как ловушка

В Vaadin нашлась хорошая пара багов про один и тот же слой интерфейса: non-modal Dialog и Popover.

Визуально это выглядит как обычная плавающая панель поверх страницы. Но для клавиатуры и скринридера всё сложнее: диалог без затемняющего фона всё равно удерживал Tab внутри себя, а non-modal popover мог открыться без понятного объявления для NVDA и VoiceOver.

Для зрячего пользователя это часто просто «панель открылась». Для пользователя с клавиатурой это может стать тупиком: фокус уже перенесли в основную страницу, нажали Tab — и интерфейс снова утащил его назад. Для пользователя со скринридером popover может появиться, но не прозвучать как новое доступное содержимое.

Я выбрал этот кейс для недельного PR: он не про один атрибут, а про общий паттерн overlay-компонентов. В PR non-modal Dialog больше не включает focus trap, а non-modal Popover получает polite-объявление своего текста или accessible name при открытии без переноса фокуса. Плюс добавлены регрессионные тесты.

Хорошая проверка для команд: если компонент называется non-modal, проверьте не только мышь. Уведите фокус за панель и нажмите Tab. Потом откройте такой popover со скринридером и убедитесь, что пользователь понял: что-то появилось и что именно.

Кейс подготовлен с помощью Accessibility Auditor Skill.

Proof:
issue #11971
issue #11974
PR #11984
Когда ответ есть, но VoiceOver его не видит

В GitHub появился хороший сигнал по доступности Claude Desktop на macOS: полностью незрячий разработчик пишет, что может набрать и отправить запрос, но не может прочитать ответ ассистента через VoiceOver.

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

Обходной путь у автора показательный: читать ответы через iPhone companion app или внешне проговаривать их через macOS say. Для ежедневной работы это не решение. Человек пишет на Mac, ждёт ответ там же, а читать вынужден в другом месте или через отдельную самодельную озвучку.

Здесь ломается не «удобная мелочь», а главный цикл интерфейса: вопрос → ответ → продолжение работы. Для ИИ-продукта доступность стенограммы важна не меньше, чем доступность поля ввода.

Командам стоит проверять не только «можно ли что-то отправить», а весь разговорный поток: новый ответ объявляется, текст ответа есть в дереве доступности, до последнего сообщения можно быстро дойти, фокус не застревает, а изменения после серверного рендера не выбрасывают содержимое из VoiceOver/NVDA.
VS Code + VoiceOver: доступность ломается на скорости

Свежий сигнал: в VS Code Insiders большой файл с включённым VoiceOver может превращаться в почти нерабочий редактор. Полный разбор ниже.
Когда доступность ломается не на кнопке, а на скорости

В свежем issue по VS Code Insiders пользователь VoiceOver описал неприятную вещь: если открыть файл больше примерно 400 строк, редактор начинает сильно тормозить. С включённым VoiceOver и accessibility support процессор почти упирается в 100%, а задержка растёт вместе с размером файла. Расширения он отключал, то есть это не похоже на конфликт с плагином.

Для зрячего пользователя это может выглядеть как «редактор подлагивает». Для незрячего разработчика это быстро превращается в рабочий стоп: нельзя нормально читать код, перемещаться по файлу, проверять изменения и просто писать. Автор прямо пишет, что сейчас из-за этого невозможно работать.

Здесь простой урок для команд: доступность держится ещё и на скорости. Если интерфейс формально читается, но с экранным диктором начинает зависать на обычном рабочем файле, он всё равно недоступен.

Проверять нужно живой сценарий, а не маленькую демо-страницу. Возьмите большой файл, длинный список, таблицу, ленту, историю сообщений. Включите экранный диктор и посмотрите, остаётся ли интерфейс управляемым по скорости, фокусу и отклику. Иначе баг будет найден уже тем человеком, которому этот интерфейс нужен для работы.
Чатбот есть, а поговорить с ним нельзя

В issue по Frag Integreat проверяли чатбот сразу на Android, iOS и Windows. Для экранного диктора он местами превращается в один большой блок: нельзя пройти по ответу, нормально попасть в поле ввода, услышать новый ответ или удержать фокус внутри чата.

Проверять нужно весь разговор: открытие, поле вопроса, сообщения, объявление новых ответов, фокус и безопасное закрытие.

Источник: digitalfabrik/integreat-app#4223
Чатбот есть, а поговорить с ним нельзя

В Integreat завели отдельный issue по экранному доступу к Frag Integreat - их чатботу помощи. Проверяли сразу Android, iOS и Windows, и проблема не сводится к одной подписи на кнопке.

На Android экранный диктор несколько раз произносит «Frag Integreat», а весь блок чата воспринимается как один элемент. Из-за этого нельзя нормально пройти по ответу бота, выбрать часть текста и, что хуже, доступно ввести вопрос в поле ввода.

На iOS фокус иногда попадает не на ту кнопку: например, вместо меню можно оказаться на Back и случайно закрыть чат. На Windows при открытии и после ответа диктор уходит в заголовки или даже начинает читать страницу за чатботом, а новое сообщение не объявляется.

Для пользователя это не косметика. Чат помощи обещает ответить на вопрос, но человек с экранным диктором может не добраться до поля ввода, не услышать новый ответ или потерять фокус внутри окна.

Я бы здесь проверял не «есть ли aria-label», а весь разговорный путь: фокус при открытии чата, отдельные элементы сообщения, доступное поле ввода, объявление новых ответов, удержание фокуса внутри чата и безопасное закрытие без случайного Back.

Источник: digitalfabrik/integreat-app#4223