Всё про доступность интерфейсов
7 subscribers
116 photos
193 links
Download Telegram
Код на экране есть, а NVDA слышит только «blank»
⠀
Свежий баг freeCodeCamp: в Responsive Web Design встроенный редактор постепенно теряет доступность с NVDA, а с первого CSS-урока становится почти непригодным.
⠀
Для курса программирования доступность редактора — не боковая настройка. Это сама возможность учиться.
Когда урок по коду становится «blank»
⠀
В freeCodeCamp появился свежий баг: пользователь проходит Responsive Web Design с NVDA 2026.1.1, Windows 11 и Chrome. В ранних HTML-уроках встроенный редактор ещё читается. Дальше начинаются сбои: стрелки перестают нормально читать код, Ctrl+E уже ненадёжно включает режим доступности редактора, а Alt+F1 обещан, но не открывает дополнительные настройки.
⠀
С первого CSS-урока всё ломается жёстче: при фокусе на редакторе NVDA говорит только «blank». Для зрячего ученика это всё ещё поле с кодом. Для незрячего — место, где нельзя прочитать текущую строку, проверить символ, исправить ошибку и продолжить обучение.
⠀
Здесь важен не только сам Monaco editor. Если продукт учит программированию, доступность редактора — это не второстепенная настройка. Это сама дверь в курс.
⠀
Командам стоит проверять такие редакторы не на первом пустом примере, а на всём пути: разные уроки, уже заполненный код, Ctrl+E, стрелки, удаление, вставка, подсказки, ошибки и переходы между разделами. И отдельно — что после смены шаблона урока экранный диктор не начинает видеть вместо кода пустоту.
⠀
Источник: freeCodeCamp/freeCodeCamp#68957
Список может быть доступен — и всё равно читаться в неправильном порядке
⠀
В Shopify FlashList нашли Android-баг: inverted-чат визуально выглядит нормально, но TalkBack идёт по сообщениям наоборот. Причина — переворот через transform: экран поменялся, accessibility-иерархия осталась в старом порядке.
⠀
Полный разбор ниже.
Когда список визуально перевернули, TalkBack тоже начал читать его наоборот
⠀
В Shopify FlashList появился хороший продолжение истории про чаты на Android. Проблема не в том, что сообщения вообще недоступны. Они доступны, но жест «следующий элемент» у TalkBack ведёт к предыдущему сообщению, а жест «предыдущий» — к следующему.
⠀
Для зрячего пользователя чат выглядит нормально. Для человека с TalkBack разговор превращается в ленту, которую надо читать против привычных жестов. Это особенно плохо в переписке: порядок сообщений — не украшение, а часть смысла.
⠀
Интересная деталь из PR с исправлением: причина связана с тем, как inverted-список делали через `rotate(180deg)`. Визуальный порядок поменялся, а порядок детей в нативной accessibility-иерархии на Android остался прежним. В итоге интерфейс на экране и интерфейс для экранного диктора разошлись.
⠀
Что проверять командам: если список, чат, таблицу или карусель переворачивают через transform, virtualization или хитрый layout, надо пройти не только глазами и мышью. Включить TalkBack/VoiceOver, пройти жестами «следующий/предыдущий» и проверить, совпадает ли смысловой порядок с тем, что пользователь считает порядком на экране.
⠀
Фокус на элементе ещё не означает, что порядок чтения правильный.
Reduce Motion - это не «выключить красоту»
⠀
В SurveyJS открыли issue: библиотека умеет глобально выключать анимации через настройку разработчика, но не слушает системное prefers-reduced-motion. То есть человек уже включил «уменьшить движение» в ОС, а анкета всё равно может показывать переходы, smooth scroll, появление/исчезновение элементов и будущий focus mode с полноэкранными слайдами.
⠀
Это бьёт не только по «визуальному комфорту». Для людей с вестибулярной чувствительностью движение после каждого ответа может вызвать тошноту, головокружение или просто сорвать прохождение формы. А форма часто не развлечение: запись, заявка, обучение, обратная связь, госуслуга.
⠀
Хорошая деталь в issue SurveyJS: CSS-медиа-запроса мало. Если анимация управляет ещё и JS-таймерами удаления DOM-элементов, надо синхронизировать оба слоя. Иначе визуально всё «замерло», а интерфейс всё равно ждёт невидимую паузу.
⠀
Для команд простой тест: включить Reduce Motion в системе и пройти главный сценарий заново. Движение должно исчезнуть без отдельной настройки в приложении, а переключение системной настройки должно срабатывать без перезагрузки страницы.
TalkBack после перелистывания теряет текст
⠀
Свежий багрепорт по Android-читалке Areada: страница визуально сменилась, а экранный диктор не может нормально читать новый текст. Для читалки это ломает главный сценарий - чтение после перехода на следующую страницу.
TalkBack перелистывает страницу, но потом не читает текст
⠀
В GitHub появился свежий багрепорт по Android-читалке Areada: после перелистывания страницы жестом двумя пальцами справа налево TalkBack перестаёт нормально читать текст на новой странице. Пользователю приходится уйти на домашний экран через переключатель приложений и вернуться обратно, чтобы чтение снова ожило.
⠀
Для обычного интерфейса это выглядело бы как мелкая странность. Для читалки это ломает главный сценарий: человек открыл книгу или документ, перевернул страницу и потерял доступ к содержимому.
⠀
Здесь важный момент не в том, что «нужно добавить подписи». В таких экранах надо проверять сам переход: обновилась ли accessibility tree после перелистывания, не остался ли экранный диктор на старом слое, куда попал фокус, можно ли сразу читать новый текст, есть ли понятный способ вернуться назад и продолжить.
⠀
Хороший тест простой: включить TalkBack, открыть длинный текст, несколько раз перелистнуть страницу жестом, прочитать новую страницу подряд и попробовать вернуться. Если после перехода нужен трюк с переключателем приложений - страница визуально сменилась, но интерфейс для экранного доступа не сменился нормально.
Когда кнопка есть, но у неё нет имени
⠀
Свежий кейс: в PTSBuilder левая панель инструментов видима, но важные icon-only кнопки не имеют доступных имён. Полный разбор ниже.
Когда кнопка есть, но у неё нет имени
⠀
В свежем issue по PTSBuilder нашли простой, но неприятный слом: вся левая панель инструментов сделана иконками без доступных имён.
⠀
Визуально там есть кнопки: открыть панель деталей, obstacle, erase, Clear All Parts, Clear All Obstacles. Но подписи живут только в hover-tooltip через div. Для screen reader это не имя кнопки. Для клавиатурного пользователя такой tooltip тоже бесполезен: фокус на кнопку пришёл, а что она делает - непонятно.
⠀
Особенно плохо, что две кнопки ещё и разрушительные. Если незрячий пользователь слышит просто «button» и не понимает, что это очистка всех деталей или всех препятствий, интерфейс уже не даёт безопасно работать.
⠀
Здесь вывод не в том, чтобы «добавить aria-label везде». Проверять надо сам рабочий путь: можно ли без мыши узнать назначение каждой иконки, отличить опасное действие от обычного, увидеть/услышать состояние вроде expanded, и не держится ли подсказка только на hover.
⠀
Хороший быстрый тест для команды: если getByRole("button", { name: ... }) не находит важную кнопку, скорее всего, пользователь с экранным диктором её тоже не найдёт нормально.
Когда доступность не ломается сразу, а уходит по кускам
⠀
В OPNsense открыли свежий issue: слепой пользователь пишет, что веб-интерфейс файрвола раньше был заметно доступнее, а в версиях перед 26 начал деградировать.
⠀
Конкретика неприятная. В выпадающих списках при выборе опции экранный диктор произносит только “section section”. В обзоре интерфейсов и сервисов пропали подписи статусов и кнопок restart/stop. То есть админ вроде бы видит те же таблицы, селекты и кнопки, но пользователь со screen reader уже не может уверенно понять, какой интерфейс в каком состоянии и какую службу он сейчас остановит или перезапустит.
⠀
Для панели управления сетью это не косметика. Ошибка здесь может стоить отключённого сервиса, неверной настройки или просто полной зависимости от зрячего помощника в момент, когда надо быстро чинить доступ.
⠀
Хороший тест для таких интерфейсов: после каждого крупного релиза пройти не только “страница открылась”, а реальные админские сценарии с экранным диктором. Селект должен объявлять выбранный пункт. Статус должен читаться вместе с названием объекта. Кнопка остановки или перезапуска должна говорить, что именно она изменит.
⠀
И ещё: если продукт уже был доступным, это не навсегда. Доступность надо держать регрессионными проверками, как авторизацию, миграции и безопасность.
⠀
Источник: opnsense/core#10605
Статус сообщения - не декоративная галочка
⠀
Свежий TalkBack-сигнал по bitchat-android: приватный чат может визуально показывать ✓, ✓✓, ○ или ⚠, но незрячему пользователю не объяснять, отправлено сообщение, доставлено или упало.
⠀
Полный разбор ниже.
В мессенджере статус сообщения - не декоративная галочка
⠀
В bitchat-android открыли issue: с TalkBack приватные сообщения можно отправлять, но статус «отправляется / отправлено / доставлено / ошибка» озвучивается как сырые значки ✓, ✓✓, ○, ⚠ или вообще непонятно. Новые входящие сообщения тоже не объявляются, если фокус стоит в поле ввода.
⠀
Для зрячего это мелкая иконка в пузыре. Для незрячего пользователя это ответ на базовый вопрос: сообщение ушло, дошло или надо повторить? В приватном чате эта разница важна.
⠀
Отдельно там всплыл хороший тревожный пример: «panic wipe» висит на тройном тапе по заголовку, без понятного имени и, вероятно, без нормальной альтернативы для TalkBack. Деструктивное действие нельзя прятать в жест, который часть пользователей не сможет надёжно выполнить или даже обнаружить.
⠀
Что проверять: статусы должны иметь человеческие labels, новые сообщения - аккуратное live-объявление, кастомные Canvas/WebView элементы - семантику, а опасные действия - доступный путь и подтверждение.
⠀
Источник: issue #747 в permissionlesstech/bitchat-android
Карусель может быть доступной только на вид
⠀
В eBay Evo Web открыт баг про ebay-carousel: на Android Chrome с TalkBack виртуальный курсор внутри карточек «случайно» пропускает элементы, а свайпы TalkBack начинают прокручивать карусель вместо перехода по содержимому.
⠀
На практике это бьёт по задаче. Если в карточке есть цена, продавец, кнопка, условие доставки или действие «добавить», человек может услышать часть карточки и сразу улететь к следующему контейнеру. Визуально лента живёт, а маршрут обследования интерфейса ломается.
⠀
В комментарии разработчик нашёл два вероятных места: список карусели - настоящий горизонтальный scroll container со scroll-snap, а каждый li получает aria-hidden="true", если карточка не полностью видима с точностью примерно до сотых пикселя. Во время прокрутки карточка может то появляться, то исчезать из дерева доступности.
⠀
Что проверить командам:
- TalkBack/VoiceOver проходит все элементы каждой карточки по порядку;
- свайп экранного диктора не превращается в прокрутку карусели;
- частично видимые и анимирующиеся карточки не выдёргивают полезный контент из дерева доступности;
- у карусели есть понятная клавиатурная и экранная модель: где текущая карточка, куда движемся, что можно открыть.
⠀
Для товарных, новостных и обучающих каруселей это особенно важно. Карусель часто ставят туда, где лежит главный выбор пользователя. Если этот выбор нельзя последовательно прочитать и активировать без зрения, это уже не декор, а барьер в основном сценарии.
⠀
Источник: eBay/evo-web#333
MakeCode сделал блочные редакторы чуть менее закрытым клубом
⠀
В релизе 2026 для micro:bit появилась поддержка экранных дикторов в блочном редакторе. Важная деталь: они не просто подписали кнопки, а описали рабочий путь - клавиатура, структура блоков, вложенность, задания и материалы для учителей.
⠀
Полный разбор ниже.
MakeCode сделал блочные редакторы чуть менее закрытым клубом
⠀
В июльском релизе Microsoft MakeCode for micro:bit появилась поддержка экранных дикторов в блочном редакторе. Micro:bit отдельно описал, что это делали вместе с Blockly, учителями и незрячими или слабовидящими учениками.
⠀
Почему это больше, чем приятная новость? Блочное программирование часто выглядит как лёгкий вход в код: перетащи блоки, соедини, запусти. Но для человека с экранным диктором или без мыши это может быть не входом, а стеной. Если рабочее пространство живёт только как визуальная схема, ученик слышит отдельные элементы, но не может нормально понять структуру программы, вложенность, место блока и следующий шаг.
⠀
В MakeCode важна именно связка, а не одна галочка «доступно». Клавиатурное управление теперь включено по умолчанию. Поддерживаются NVDA, JAWS, Narrator, VoiceOver и ChromeVox. В режиме для экранного диктора есть жёсткие остановки при обходе блоков и звуковая подсказка при смене уровня вложенности. На стороне micro:bit добавили отдельные стартовые задания, подсказки для учителей, тактильные материалы и FAQ: как попасть в рабочую область, как скачать программу на устройство, что делать с браузерным caret browsing.
⠀
Вот что стоит забрать для интерфейсов с канвасом, карточками, drag-and-drop и визуальными схемами: нельзя ограничиться подписями кнопок. Нужно дать полноценный путь выполнения задачи без мыши и зрения: найти рабочую область, понять структуру, выбрать элемент, переместить или изменить его, проверить результат и вернуться назад без потери контекста.
⠀
Если продукт учит, настраивает, проектирует или собирает что-то из визуальных частей, тест должен быть простым: может ли человек пройти тот же урок или сценарий с клавиатурой, экранным диктором и, при необходимости, тактильной/текстовой опорой? Если нет - это не альтернативный способ использования, а отдельная дорожка для тех, кого основной интерфейс не пустил внутрь.
Инсталлятор тоже часть продукта
⠀
Если toggle и диалог видны на экране, это ещё не значит, что пользователь экранного диктора сможет выбрать опции и услышать важное подтверждение.
Инсталлятор тоже часть продукта
⠀
В issue FlyByWire Installer #550 пользователь экранного диктора BlindPilot93 описал не абстрактную «нужна доступность», а обычный путь установки.
⠀
В инсталляторе много переключателей сделаны не как стандартные чекбоксы. Для зрячего это может выглядеть как нормальный toggle. Для screen reader user это уже вопрос: что это за элемент, включён он или выключен, можно ли им управлять предсказуемо.
⠀
Второй пример ещё показательнее: диалоги с общим размером скачиваемых пакетов появляются визуально, но не как настоящие модальные окна. Они оказываются в начале документа, куда пользователь экранного диктора обычно не попадает в момент действия. То есть важное предупреждение вроде бы есть, но человек может его просто не услышать.
⠀
Это мешает не «красоте интерфейса», а установке и обновлению софта: выбрать нужные опции, понять объём загрузки, не пропустить подтверждение.
⠀
Что проверять командам: все переключатели — как реальные checkbox/switch с именем и состоянием; все подтверждения — как модальные диалоги с фокусом внутри, понятным заголовком, кнопками и возвратом фокуса назад. Особенно в инсталляторах, checkout, настройках и обновлениях: это места, где ошибка стоит дороже обычного клика.
Карта есть, маркера для TalkBack нет
⠀
В MapLibre React Native нашли баг: маркер рисуется на Android-карте, но его обёртка остаётся 0×0, поэтому TalkBack вообще не видит этот объект.
⠀
Полный разбор ниже.
Видимый маркер на карте может быть невидимым для TalkBack
⠀
В MapLibre React Native открыли хороший баг по Android: React-компонент внутри Marker рисуется на карте, но полностью отсутствует в дереве доступности. Пользователь TalkBack не может сфокусировать маркер, не слышит его название, а uiautomator dump вообще не показывает узел маркера.
⠀
Причина почти бытовая: обёртку маркера перемещают по координатам x/y, но ей не задают реальный layout-размер. Визуально дочерний компонент всё равно виден, потому что clipping отключён. А для Android accessibility это 0×0 view, и такой кусок интерфейса просто исчезает.
⠀
Для карт это не мелочь. Маркер может быть точкой доставки, автобусной остановкой, объектом на маршруте, аварией, рестораном, чем угодно. Зрячий пользователь видит точку и нажимает. Пользователь TalkBack слышит карту без этих объектов.
⠀
Что стоит проверять командам: не только “есть ли label у маркера”, а попадает ли маркер в accessibility tree с реальными bounds, можно ли дойти до него свайпами TalkBack, слышно ли название и не ломается ли нажатие после фикса. Особенно если маркеры, подсказки или карточки поверх карты рисуются через кастомные обёртки.
Пароль скрыт на экране, но VoiceOver читает его вслух
⠀
Свежий баг во Flutter: obscureText: true маскирует поле визуально, но экранный диктор на iOS может произносить вводимые символы. Проверять нужно не только точки в поле, а весь путь ввода с VoiceOver/TalkBack.
⠀
Полный разбор ниже.
Когда пароль скрыт на экране, но произносится вслух
⠀
В Flutter завели свежий баг: если в iOS-приложении поле сделано как пароль через obscureText: true, VoiceOver при вводе может читать реальные символы вслух. Визуально всё выглядит правильно: поле «замаскировано», на экране пароль не виден. Но для человека со включённым VoiceOver секрет уже может прозвучать рядом с другими людьми.
⠀
Это не просто «неудобное озвучивание». Парольное поле обычно используют в ситуации, где пользователь рассчитывает на приватность: вход в аккаунт, кошелёк, почта, рабочий сервис, медкарта. Если экранный диктор произносит вводимые символы, незрячий пользователь получает выбор без нормального выбора: либо вводить пароль и рисковать утечкой на слух, либо искать обходной путь.
⠀
Для команд вывод простой: недостаточно проверить, что пароль визуально закрыт точками. Нужно включить VoiceOver/TalkBack и пройти сам ввод: что произносится при фокусе, при наборе, при удалении, при автозаполнении, при ошибке и при повторном показе поля.
⠀
Особенно важно не доверять только свойству компонента вроде obscureText. В фреймворке, браузере или нативном мосте может быть баг, и тогда визуальная защита остаётся, а звуковая — ломается.
⠀
Источник: flutter/flutter#190320