Всё про доступность интерфейсов
7 subscribers
116 photos
193 links
Download Telegram
Кейс по доступности: dropdown-меню в UI Kit.

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

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

Что изменили: добавили для триггера меню aria-haspopup, aria-expanded и связь с открытым меню через aria-controls. Для выбранных пунктов добавили доступное состояние, а декоративную галочку скрыли от скринридера.

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

Такой разбор и минимальную правку я делаю через Accessibility Auditor Skill: он помогает быстро найти пользовательскую проблему, проверить WCAG/RGAA-смысл и довести её до небольшого безопасного PR.

Доказательство:

Issue: suitenumerique/ui-kit#183

PR: suitenumerique/ui-kit#227
Etherpad и экранный доступ: подсказка была в коде, но не в дереве доступности

Если элемент нужен NVDA, VoiceOver или другому экранному доступу, его нельзя прятать через hidden. Иначе aria-describedby может ссылаться в пустоту.

Полный разбор ниже.
Если подсказка спрятана через hidden, экранный доступ её тоже не видит

В Etherpad дошли до неприятного бага: редактор мог показывать клавиатурную подсказку в коде, но не отдавать её экранному доступу. Причина простая: элемент с подсказкой был создан с hidden=true, а aria-describedby ссылался уже на узел, которого нет в дереве доступности.

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

Хорошая правка здесь не в том, чтобы «добавить ARIA». Команда убрала hidden, добавила запасной текст для подсказки, если переводы ещё не загрузились, и отдельно защитила skip link: доступность не должна быть настройкой, выключенной по умолчанию.

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

Источник: жалоба в Etherpad и PR с исправлением.
Кейс дня: состояние dropdown стало понятнее для screen reader

Коротко: новый разбор issue → audit → PR по доступности интерфейса. Полный текст — следующим сообщением.
Кейс дня: состояние dropdown стало понятнее для screen reader

В UI Kit La Suite numérique был открытый accessibility issue по DropdownMenu: триггер открывал меню, но не сообщал вспомогательным технологиям, что это именно меню и открыто оно сейчас или закрыто.

Было: пользователь доходил до кнопки, нажимал Enter — меню появлялось, но screen reader не получал явного состояния expanded/collapsed. При повторной навигации было сложнее понять, что произошло и куда дальше двигаться.

Что мешало: для зрячего пользователя изменение видно визуально, а для пользователя screen reader состояние компонента должно быть выражено программно. Без aria-expanded и связи с меню интерфейс хуже объясняет сам себя.

Что изменили: в DropdownMenu добавлены aria-haspopup="menu", aria-expanded и связь триггера с меню через aria-controls во время открытия.

Стало: триггер теперь сообщает, что открывает меню, и отдаёт актуальное состояние. Это маленький PR, но он закрывает конкретный кусок блокирующей проблемы и делает компонент спокойнее для клавиатурной и screen reader-навигации.

Разбор и правка сделаны с помощью Accessibility Auditor Skill — инструмента для поиска и исправления accessibility-проблем в реальных интерфейсах.

Доказательство:
Issue: https://github.com/suitenumerique/ui-kit/issues/183
PR: https://github.com/suitenumerique/ui-kit/pull/228
1
Когда ИИ-ответ есть на экране, но его нет для VoiceOver

В свежем issue по Warp описали неприятный сбой: VoiceOver не читает ответы агента и вывод терминала в панели агента. Вместо текста пользователь слышит внутреннюю строку вроде MaybeHoverSecret { secret_handle: None }.

Это не декоративная проблема. Если человек работает через экранный доступ, он не может прочитать ответ ИИ, проверить вывод команды или вернуться к результату. При этом документы в соседнем редакторе Warp читаются через системное чтение, значит проблема, похоже, в отрисовке панели агента/терминала.

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

Я бы отдельно проверял все панели с потоковым текстом: ответы ИИ, терминал, логи, чат, уведомления.

Источник: warpdotdev/warp#11125.
👍1
Сегодняшний кейс — dropdown-меню в UI Kit La Suite.

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

Что мешало пользователю: клавиатурный пользователь мог потерять текущий пункт меню из-за слабого фокуса, а пользователь screen reader получал меньше информации о том, открыто ли меню и какие пункты уже выбраны.

Что изменили: добавили связь триггера с меню через ARIA-состояния, передали состояние выбранных пунктов через aria-checked и усилили видимый фокус на пунктах меню.

Стало: состояние dropdown стало понятнее для screen reader, а клавиатурная навигация — заметнее визуально. Это не закрывает весь большой issue целиком, но убирает несколько практичных барьеров небольшим PR.

Такие точечные исправления хорошо ложатся в подход Accessibility Auditor Skill: найти конкретный пользовательский барьер, проверить риск и отправить минимальную полезную правку.

Доказательства:

Issue: suitenumerique/ui-kit#183

PR: suitenumerique/ui-kit#229
В MakeCode нашли простую, но тяжёлую проблему: блоки видны, а с клавиатуры до них не добраться

В свежем issue по Microsoft MakeCode для micro:bit описали баг в редакторе проекта. Пользователь открывает раздел Music, а дальше не может перейти к внутренним элементам: вводу мелодии, темпу, тону, выпадающим спискам. Фокус просто не заходит в эти контролы.

Отдельно в issue сказано, что похожее замечено и в других деревьях редактора: Basic, Input, LED, Radio, Loops, Logic. То есть это не один кривой элемент, а риск на уровне навигации по целому типу интерфейса.

Кого это бьёт: людей, которые работают с клавиатуры, и пользователей screen reader. Для них “видимый блок в редакторе” ещё не значит “доступный блок”. Если фокус не попадает внутрь, человек не может поменять параметры и фактически теряет часть функциональности.

Для команд здесь проверка довольно приземлённая: после выбора раздела нужно не только смотреть, появился ли UI на экране. Нужно пройти его с клавиатуры по порядку и убедиться, что каждый внутренний контрол достижим, понятен и работает без мыши.

Особенно это важно в образовательных инструментах. Если ребёнок или преподаватель не может собрать пример с музыкой только потому, что фокус застрял снаружи, это уже не “мелкий баг доступности”. Это сломанный учебный сценарий.
Кейс доступности дня: меньше шума для screen reader

В браузерном расширении MindTab панель Writing Assistant обновляется прямо во время набора текста: тон, статистика, подсказки, статус сервера.

Было: вся панель была помечена как live region. Из-за этого screen reader мог озвучивать почти каждое изменение внутри панели, даже если пользователю нужна только новая подсказка по тексту.

Что мешало: при наборе длинного сообщения пользователь получал поток лишних объявлений. Это сбивает фокус, мешает писать и превращает полезного помощника в источник аудио-шума.

Что изменили: убрали live region со всей панели и оставили polite-объявления только на контейнере с подсказками. Теперь статичные части панели — тон, статистика, служебные индикаторы — не должны перебивать пользователя при каждом обновлении.

Стало: screen reader получает более точный сигнал: объявлять важные подсказки, а не всё подряд.

Такие кейсы я разбираю через Accessibility Auditor Skill: он помогает быстро отделить реальную проблему доступности от косметики и довести её до маленького полезного PR.

Доказательство:

Issue: github.com/AetherAssembly/MindTab/issues/14

PR: github.com/AetherAssembly/MindTab/pull/19
Когда alert есть в речи, но пропадает на брайлевском дисплее

В NVDA сегодня завели свежий bug: содержимое элемента с role="alert" озвучивается голосом, но на брайлевском дисплее показывается только слово “alert”. Пользователь слышит “this is an alert, alert”, а на брайлевской строке видит почти пустую метку.

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

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

В важных сценариях - ошибки формы, оплата, риск потери данных - стоит проверять, что попало в речь и на брайлевский вывод. Иначе команда видит правильный role="alert", а пользователь всё равно остаётся без текста.

Источник: issue nvaccess/nvda#20172
Кейс дня: кнопки, которые «видны», но не называются

Коротко: новый разбор issue → audit → PR по доступности интерфейса. Полный текст — следующим сообщением.
Кейс дня: кнопки, которые «видны», но не называются

Нашёл в Personal Planner типичную проблему доступности: часть действий была понятна только визуально — по иконке, эмодзи, цветному кружку или закрашенной клетке.

Было
Screen reader мог встретить кнопку без понятного имени. Например: ячейка привычки, день тренировки, выбор настроения или цвета выглядели нормально на экране, но для незрячего пользователя звучали как безымянные элементы управления.

Что мешало пользователю
Нельзя быстро понять, что произойдёт после нажатия: удалить привычку, отметить день, снять отметку, выбрать настроение или поменять цвет. Это повышает риск ошибки и делает интерфейс утомительным.

Что изменили
Добавил понятные accessible names и состояние для toggle-кнопок:

• «Delete Morning run» вместо безымянной иконки корзины
• «Mark gym attendance for May 19» / «Remove gym attendance for May 19»
• «Set mood to Happy»
• «Choose blue accent color»
aria-pressed там, где кнопка работает как переключатель

Стало
Теперь пользователь screen reader слышит не просто «button», а конкретное действие и текущее состояние. Интерфейс остаётся тем же визуально, но становится понятнее для клавиатуры и ассистивных технологий.

Такие проверки я делаю через Accessibility Auditor Skill: он помогает быстро пройтись по исходникам, найти проблемные паттерны и превратить аудит в маленький полезный PR.

Доказательство
Issue: https://github.com/TemaDeveloper/personal_planner/issues/25
PR: https://github.com/TemaDeveloper/personal_planner/pull/28
Когда вход ломается для VoiceOver, это уже не мелкий баг

В Notesnook открыли GitHub-задачу #9845: на iOS VoiceOver не может активировать поля «имя пользователя» и «пароль» на экране входа. На вебе часть кнопок в навигации и панелях редактора остаётся без понятных подписей для NVDA, JAWS и VoiceOver.

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

Я бы здесь проверял две вещи до релиза: можно ли пройти вход только с экранным доступом и клавиатурой; понятно ли называется каждый интерактивный элемент.

Источник: streetwriters/notesnook#9845
Кейс доступности: выпадающий список, которым нельзя нормально управлять с клавиатуры

Коротко: новый разбор issue → audit → PR по доступности интерфейса. Полный текст — следующим сообщением.
Кейс доступности: выпадающий список, которым нельзя нормально управлять с клавиатуры

В WindoM был кастомный GlassSelect: визуально он выглядел как обычный dropdown, но для пользователя клавиатуры и screen reader всё было хуже, чем кажется.

Было:
• Dropdown открывался с клавиатуры.
• Но ArrowUp / ArrowDown не перемещали активный пункт.
• Home / End не прыгали в начало и конец списка.
• Escape не закрывал список с возвратом фокуса на кнопку.
• Enter / Space не выбирали текущий пункт после навигации.

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

Что изменили:
• Добавили управление ArrowUp / ArrowDown, Home / End, Enter / Space и Escape.
• Сохранили фокус на trigger-кнопке и возвращаем его туда после выбора или закрытия.
• Добавили связь trigger listbox через ARIA.
• Добавили визуальное состояние активного пункта при клавиатурной навигации.

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

Такие проверки удобно раскладывать по компонентам с помощью Accessibility Auditor Skill: он помогает быстро понять, где проблема в UX для клавиатуры и screen reader, а где достаточно маленького точечного PR.

Доказательство:
Issue: https://github.com/YehudaBriskman/WindoM/issues/243
PR: https://github.com/YehudaBriskman/WindoM/pull/269
Когда картинку нельзя спрятать от VoiceOver

В Expo завели свежую задачу по expo-image на iOS. Сценарий простой: внутри Pressable лежит Image, разработчик ставит accessible={false} и accessibilityElementsHidden={true}, чтобы VoiceOver не читал эту картинку. Но при фокусе VoiceOver произносит: hello world.

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

Я бы здесь проверял свойства в коде и реальное поведение. Особенно внутри кликабельных контейнеров. Открыть устройство, включить VoiceOver и пройти сценарий фокусом: что произносится, в каком порядке и не вылезает ли в речь то, что должно было быть скрыто.

Источник: expo/expo#46039
Кейс доступности: важные сообщения должны быть услышаны

Коротко: новый разбор issue → audit → PR по доступности интерфейса. Полный текст — следующим сообщением.
Кейс доступности: важные сообщения должны быть услышаны

Нашёл в Ride The Lightning проблему из WCAG 4.1.3: динамические сообщения появлялись на экране, но не всегда объявлялись скринридером.

Было: пользователь вводит пароль, получает ошибку входа или видит состояние загрузки. Визуально сообщение есть, но для незрячего пользователя оно могло пройти мимо — приходилось вручную искать, что изменилось.

Что мешало: ошибки формы и статус загрузки не были оформлены как live regions/status messages. Скринридер не обязан автоматически озвучивать такие изменения, если интерфейс явно не сообщает их ассистивным технологиям.

Что изменили: добавил семантику для объявлений:


• загрузка RTL теперь имеет role="status", aria-live="polite" и понятное имя для спиннера;


• ошибки пароля в login/auth формах теперь объявляются как role="alert";


• сообщение об ошибке входа объявляется сразу, а logout/session-сообщение — в более спокойном polite-режиме.

Стало: пользователь со скринридером получает обратную связь в момент, когда она появилась: «пароль обязателен», «ошибка входа», «идёт загрузка». Это меньше неопределённости и меньше лишней навигации по странице.

Такие кейсы я разбираю с помощью Accessibility Auditor Skill: он помогает быстро пройтись по потоку, найти место, где интерфейс визуально работает, но программно молчит, и довести это до небольшого безопасного PR.

Доказательство:

Issue: Ride-The-Lightning/RTL#1561

PR: Ride-The-Lightning/RTL#1603
NVDA и быстрый Tab: когда озвучка догоняет фокус

В свежей задаче NVDA описали неприятную вещь: если быстро пройти по ссылкам клавишей Tab, NVDA может произнести текущий и предыдущий элемент подряд. На сайте NV Access автор останавливается на Get Help, а слышит сначала Download, потом Get Help. В Firefox, по отчёту, шум может быть ещё сильнее - до трёх-четырёх прошлых ссылок.

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

Для команд здесь простой урок: быстрые сценарии тоже надо тестировать. Медленный проход по Tab может выглядеть нормально, а быстрое движение по меню, формам, результатам поиска и диалогам - уже нет.

Источник: issue nvaccess/nvda#20197.
Маленький PR, который делает bottom sheet понятнее для screen reader

Коротко: новый разбор issue → audit → PR по доступности интерфейса. Полный текст — следующим сообщением.
Маленький PR, который делает bottom sheet понятнее для screen reader

Нашёл в Artigen open issue по доступности: bottom sheet открывался как меню, но при появлении не переводил фокус внутрь и не озвучивал заголовок.

Было: пользователь открывает список действий, а screen reader может оставаться «снаружи» — непонятно, что появилось и где теперь работать.

Что изменили: при открытии ActionSheet фокус переносится на заголовок, а название sheet дополнительно озвучивается. Для desktop-dialog и mobile bottom sheet сохранены существующие роли menu/menuitem и modal semantics.

Стало: клавиатурному и screen reader-пользователю проще понять контекст: открылось меню действий, фокус внутри, можно сразу выбирать пункт или закрыть.

Такие небольшие кейсы хорошо ловит и помогает разбирать Accessibility Auditor Skill: не абстрактный “a11y audit”, а конкретное “что мешает человеку и какой минимальный PR это исправит”.

Доказательство:
Issue: https://github.com/MukundaKatta/artigen/issues/204
PR: https://github.com/MukundaKatta/artigen/pull/455