Свежий пример из JLS: приложение может быть доступным в dev-запуске, но «немым» после установки, если в упакованный runtime не попал Java Access Bridge.
Ниже - полный разбор, почему доступность надо проверять на настоящем релизном инсталляторе, а не только в IDE.
Ниже - полный разбор, почему доступность надо проверять на настоящем релизном инсталляторе, а не только в IDE.
В GitHub-issue по JLS поймали не баг в кнопках и не пропущенный aria-label, а более неприятную штуку: установленная Windows-версия Java-приложения может быть полностью «немой» для NVDA и JAWS.
Причина в сборке. Инсталлятор делает свой урезанный Java runtime через статический анализ зависимостей. А модуль
В итоге визуально приложение запускается, функции со spoken feedback могут быть написаны, но экранный диктор к установленной версии просто не подключается. Для студента на Windows это разница между «скачал MSI и работаешь» и «ищи полный JDK, запускай jar руками, если вообще можешь».
Вывод для команд простой: доступность надо проверять не только в dev-запуске. Пройдите именно тот путь, который проходит пользователь: скачал релиз, поставил, открыл, включил NVDA/JAWS/VoiceOver/TalkBack и попробовал выполнить главную задачу.
Особенно это касается Electron, Java, Qt, Flutter desktop и любых приложений с упакованным runtime. Иногда доступность ломается не в интерфейсе, а в упаковке.
Причина в сборке. Инсталлятор делает свой урезанный Java runtime через статический анализ зависимостей. А модуль
jdk.accessibility, где лежит Java Access Bridge, туда сам не попадает: код приложения на него напрямую не ссылается. Плюс в поставке нет accessibility.properties, который включает мост.В итоге визуально приложение запускается, функции со spoken feedback могут быть написаны, но экранный диктор к установленной версии просто не подключается. Для студента на Windows это разница между «скачал MSI и работаешь» и «ищи полный JDK, запускай jar руками, если вообще можешь».
Вывод для команд простой: доступность надо проверять не только в dev-запуске. Пройдите именно тот путь, который проходит пользователь: скачал релиз, поставил, открыл, включил NVDA/JAWS/VoiceOver/TalkBack и попробовал выполнить главную задачу.
Особенно это касается Electron, Java, Qt, Flutter desktop и любых приложений с упакованным runtime. Иногда доступность ломается не в интерфейсе, а в упаковке.
GitHub
FEAT-C26-7: every published installer bundles the Java Access Bridge — jdk.accessibility pinned in the jlink module list and a…
Abstract An installed JLS is inaudible to a screen reader on the flagship Windows distribution: scripts/build-installer.sh:145 derives the jlink module set from jdeps --print-module-deps --ignore-m...
Лишняя кнопка тоже может ломать доступность.
В UI5 Web Components React завели issue про TabContainer: стрелка раскрытия рядом со вкладкой попадает в JAWS как отдельная кнопка
Визуально это маленькая стрелка. Но для screen reader она становится ещё одной командой в списке кнопок. Пользователь слышит лишний «More button» и должен угадывать, часть это вкладки или отдельное действие.
Проверка для команд: в вкладках, меню и split-button-паттернах ищите не только пропущенные подписи, но и лишний интерактивный мусор в дереве доступности.
В UI5 Web Components React завели issue про TabContainer: стрелка раскрытия рядом со вкладкой попадает в JAWS как отдельная кнопка
More.Визуально это маленькая стрелка. Но для screen reader она становится ещё одной командой в списке кнопок. Пользователь слышит лишний «More button» и должен угадывать, часть это вкладки или отдельное действие.
Проверка для команд: в вкладках, меню и split-button-паттернах ищите не только пропущенные подписи, но и лишний интерактивный мусор в дереве доступности.
Лишняя кнопка тоже может ломать доступность.
В UI5 Web Components React завели issue про TabContainer: у вкладки есть подпункты, рядом с ней визуально показывается стрелка раскрытия, и эта стрелка попадает в JAWS как отдельная кнопка
На экране это может выглядеть нормально: вкладка «General Information» и маленькая стрелка рядом. Но в JAWS Button List появляется ещё один отдельный элемент «More button menu». Пользователь слышит как будто две разные точки действия и должен угадывать, что это часть той же вкладки, а не самостоятельная команда.
Интересная деталь: в SAPUI5 reference похожая стрелка сделана декоративной:
Вывод простой: доступность ломают не только невидимые кнопки. Иногда мешает наоборот лишний интерактивный мусор в дереве доступности.
Для вкладок, меню, раскрывающихся стрелок и split-button-паттернов стоит проверять не только Tab-порядок. Откройте список кнопок/ссылок в JAWS или NVDA и посмотрите, не появились ли там декоративные иконки, стрелки и внутренние «More», которые пользователь не должен выбирать отдельно.
В UI5 Web Components React завели issue про TabContainer: у вкладки есть подпункты, рядом с ней визуально показывается стрелка раскрытия, и эта стрелка попадает в JAWS как отдельная кнопка
More.На экране это может выглядеть нормально: вкладка «General Information» и маленькая стрелка рядом. Но в JAWS Button List появляется ещё один отдельный элемент «More button menu». Пользователь слышит как будто две разные точки действия и должен угадывать, что это часть той же вкладки, а не самостоятельная команда.
Интересная деталь: в SAPUI5 reference похожая стрелка сделана декоративной:
role="presentation" и aria-hidden="true". То есть screen reader видит саму вкладку и её состояние, но не техническую иконку рядом.Вывод простой: доступность ломают не только невидимые кнопки. Иногда мешает наоборот лишний интерактивный мусор в дереве доступности.
Для вкладок, меню, раскрывающихся стрелок и split-button-паттернов стоит проверять не только Tab-порядок. Откройте список кнопок/ссылок в JAWS или NVDA и посмотрите, не появились ли там декоративные иконки, стрелки и внутренние «More», которые пользователь не должен выбирать отдельно.
GitHub
Tab / TabContainer: Tab expand button (overflow arrow) incorrectly exposed as interactive element to screen readers · Issue #8900…
Description In the TabContainer component (used internally by ObjectPage), when a Tab has sub-items and its own content (the "two-click area" pattern), the expand/overflow arrow button is...
ВАЖНО: интересен и нужен ли вам этот канал?
Anonymous Poll
0%
Да: пусть приходят посты
0%
Нет: не интересно
100%
Все равно / напишу идею в бот обратной связи
Всё про доступность интерфейсов pinned «ВАЖНО: интересен и нужен ли вам этот канал?»
В VS Code есть хороший сигнал про доступность расширений.
В issue по Bookmarks незрячий пользователь описал простую вещь: он ставит закладку на строку, двигается дальше, возвращается назад - и экранный диктор не сообщает ни что закладка поставлена, ни что текущая строка уже с закладкой.
Визуально всё есть: значок в редакторе, список закладок, состояние строки. Но с JAWS, NVDA, VoiceOver или Narrator приходится лезть в отдельный список и проверять вручную. Для инструмента навигации это почти ломает смысл функции.
Мейнтейнер ответил, что VS Code пока не даёт расширениям публичный API для таких невизуальных объявлений и accessibility signals. То есть проблема не только в одном плагине, а в границе платформы.
Что проверять: если статус показан иконкой, цветом, gutter, badge или звуком, нужен второй канал. Пользователь должен узнать: действие сработало, состояние изменилось, текущий объект уже в этом состоянии.
В issue по Bookmarks незрячий пользователь описал простую вещь: он ставит закладку на строку, двигается дальше, возвращается назад - и экранный диктор не сообщает ни что закладка поставлена, ни что текущая строка уже с закладкой.
Визуально всё есть: значок в редакторе, список закладок, состояние строки. Но с JAWS, NVDA, VoiceOver или Narrator приходится лезть в отдельный список и проверять вручную. Для инструмента навигации это почти ломает смысл функции.
Мейнтейнер ответил, что VS Code пока не даёт расширениям публичный API для таких невизуальных объявлений и accessibility signals. То есть проблема не только в одном плагине, а в границе платформы.
Что проверять: если статус показан иконкой, цветом, gutter, badge или звуком, нужен второй канал. Пользователь должен узнать: действие сработало, состояние изменилось, текущий объект уже в этом состоянии.
У Dictus iOS нашли хороший пример: функция вроде бы есть, но для VoiceOver её нет.
Smart Mode включается длинным нажатием на кнопку микрофона, потом перетаскиванием на строку в веере и отпусканием. В обычном сценарии это быстрый жест. Но VoiceOver перехватывает долгий drag, а строки веера ещё и не являются accessibility elements. В итоге незрячий пользователь не может выбрать режим диктовки вообще.
Это не “чуть неудобнее”. Это другой продукт: зрячий пользователь меняет режим прямо в клавиатуре, а пользователь VoiceOver остаётся без основного действия.
Что здесь важно для интерфейсов:
• жест с drag не должен быть единственным способом выполнить действие;
• для iOS стоит добавить accessibility actions / rotor actions или отдельное действие в списке режимов;
• кнопка микрофона должна иметь понятное имя, состояние и текущий выбранный режим;
• тестировать надо не “кнопка фокусируется”, а полный путь: найти микрофон, выбрать режим, начать диктовку, услышать состояние, отменить или изменить выбор.
Если интерфейс держится на красивом жесте, простой контрольный вопрос такой: что сделает человек, который управляет телефоном не пальцем по экрану, а VoiceOver, switch control или голосом?
Источник: getdictus/dictus-ios#397
Smart Mode включается длинным нажатием на кнопку микрофона, потом перетаскиванием на строку в веере и отпусканием. В обычном сценарии это быстрый жест. Но VoiceOver перехватывает долгий drag, а строки веера ещё и не являются accessibility elements. В итоге незрячий пользователь не может выбрать режим диктовки вообще.
Это не “чуть неудобнее”. Это другой продукт: зрячий пользователь меняет режим прямо в клавиатуре, а пользователь VoiceOver остаётся без основного действия.
Что здесь важно для интерфейсов:
• жест с drag не должен быть единственным способом выполнить действие;
• для iOS стоит добавить accessibility actions / rotor actions или отдельное действие в списке режимов;
• кнопка микрофона должна иметь понятное имя, состояние и текущий выбранный режим;
• тестировать надо не “кнопка фокусируется”, а полный путь: найти микрофон, выбрать режим, начать диктовку, услышать состояние, отменить или изменить выбор.
Если интерфейс держится на красивом жесте, простой контрольный вопрос такой: что сделает человек, который управляет телефоном не пальцем по экрану, а VoiceOver, switch control или голосом?
Источник: getdictus/dictus-ios#397
GitHub
Smart Modes cannot be armed under VoiceOver — the fan is gesture-only · Issue #397 · getdictus/dictus-ios
Found during the #79 visual coherence pass (claudedocs/79-smart-mode-visual-coherence.md), outside the two questions it was asked. A VoiceOver user cannot arm a Smart Mode Arming is a long-press on...
Свежий issue в Linksys PrivacyGUI: карточку dashboard можно переставить с клавиатуры, и на экране всё выглядит успешно.
Но после повторного открытия страницы карточка возвращается назад. Мышиный drag сохраняется, а клавиатурный путь нет.
Главный тест для drag-and-drop альтернатив: не только «можно ли двигать без мыши», но и «сохранился ли результат после Save/Done и повторного открытия экрана».
Но после повторного открытия страницы карточка возвращается назад. Мышиный drag сохраняется, а клавиатурный путь нет.
Главный тест для drag-and-drop альтернатив: не только «можно ли двигать без мыши», но и «сохранился ли результат после Save/Done и повторного открытия экрана».
Клавиатурный путь должен сохранять результат, а не только красиво двигать карточку
Свежий issue в Linksys PrivacyGUI: на dashboard можно переставить карточку с клавиатуры. Пользователь входит в режим редактирования, Tab-ом доходит до карточки, нажимает Space, стрелками двигает её, снова Space, потом Done.
На экране всё выглядит нормально: карточка переехала. Даже семантическая подпись обновляется: было Row 1, Column 0, стало Column 1.
Но после повторного открытия страницы карточка возвращается назад. Мышиный drag сохраняется, Optimize сохраняется, а именно клавиатурный путь не пишет новое расположение в хранилище.
Это неприятный класс багов. Формально доступность как будто есть: фокус есть, клавиши работают, состояние озвучивается. Но реальная задача не выполнена. Человек с моторными ограничениями, пользователь клавиатуры, switch control или голосового управления тратит время, настраивает свой dashboard и молча теряет результат.
Здесь практический тест простой: если вы делаете drag-and-drop альтернативу, проверяйте не только сам жест.
Нужно пройти весь цикл:
1. выбрать элемент без мыши;
2. переместить или изменить его;
3. получить понятное подтверждение;
4. нажать Save/Done;
5. открыть экран заново;
6. убедиться, что результат сохранился.
Иначе получается опасная иллюзия: интерфейс «доступен» ровно до момента, когда пользователь пытается сохранить свою работу.
Свежий issue в Linksys PrivacyGUI: на dashboard можно переставить карточку с клавиатуры. Пользователь входит в режим редактирования, Tab-ом доходит до карточки, нажимает Space, стрелками двигает её, снова Space, потом Done.
На экране всё выглядит нормально: карточка переехала. Даже семантическая подпись обновляется: было Row 1, Column 0, стало Column 1.
Но после повторного открытия страницы карточка возвращается назад. Мышиный drag сохраняется, Optimize сохраняется, а именно клавиатурный путь не пишет новое расположение в хранилище.
Это неприятный класс багов. Формально доступность как будто есть: фокус есть, клавиши работают, состояние озвучивается. Но реальная задача не выполнена. Человек с моторными ограничениями, пользователь клавиатуры, switch control или голосового управления тратит время, настраивает свой dashboard и молча теряет результат.
Здесь практический тест простой: если вы делаете drag-and-drop альтернативу, проверяйте не только сам жест.
Нужно пройти весь цикл:
1. выбрать элемент без мыши;
2. переместить или изменить его;
3. получить понятное подтверждение;
4. нажать Save/Done;
5. открыть экран заново;
6. убедиться, что результат сохранился.
Иначе получается опасная иллюзия: интерфейс «доступен» ровно до момента, когда пользователь пытается сохранить свою работу.
GitHub
Dashboard: keyboard card reorder is never persisted (a11y move path reverts on reload) · Issue #1393 · linksys/PrivacyGUI
Route: uspDashboard (edit mode) · grid = package:sliver_dashboard 0.9.1 Moving a dashboard card with the keyboard updates the grid on screen but is never persisted. On reload the card snaps back to...
Карта может быть недоступной не из-за карты
В GitHub появился свежий issue по DRE Visualizations: после релиза нужно проверить MapLibre-контролы. Там уже увеличили кнопки навигации и закрытия попапа до 44×44 CSS px для coarse pointer - для пальца, стилуса и других неточных способов ввода.
Хороший маленький пример. Человек должен попасть в плюс, минус или крестик. Если рука дрожит, палец плохо слушается, экран на улице бликует или телефон тормозит, маленькая цель превращает обычное действие в серию промахов.
Что я бы проверяла:
1. Тач-контролы не меньше 44×44 px.
2. Большая зона не перекрывает текст в попапе.
3. Управление работает с клавиатуры.
4. Фокус видно.
5. Закрытие, масштаб и прокрутка страницы не конфликтуют.
Доступность карт - это не только alt-текст. Иногда это нормальный размер кнопки, чтобы человек мог реально нажать её, а не играть в пиксельную охоту.
Источник: DRE Visualizations issue #13
В GitHub появился свежий issue по DRE Visualizations: после релиза нужно проверить MapLibre-контролы. Там уже увеличили кнопки навигации и закрытия попапа до 44×44 CSS px для coarse pointer - для пальца, стилуса и других неточных способов ввода.
Хороший маленький пример. Человек должен попасть в плюс, минус или крестик. Если рука дрожит, палец плохо слушается, экран на улице бликует или телефон тормозит, маленькая цель превращает обычное действие в серию промахов.
Что я бы проверяла:
1. Тач-контролы не меньше 44×44 px.
2. Большая зона не перекрывает текст в попапе.
3. Управление работает с клавиатуры.
4. Фокус видно.
5. Закрытие, масштаб и прокрутка страницы не конфликтуют.
Доступность карт - это не только alt-текст. Иногда это нормальный размер кнопки, чтобы человек мог реально нажать её, а не играть в пиксельную охоту.
Источник: DRE Visualizations issue #13
Reduced motion как настройка продукта
В ProgressRPG завели issue про отдельный переключатель «уменьшить движение» в настройках аккаунта.
Предложение аккуратное: при первом открытии взять системный
Это помогает людям с вестибулярной чувствительностью, ADHD, мигренями и перегрузом от анимаций. Плюс обычный случай: пользователь может не хотеть менять всю ОС из-за одной игры, где двигаются прогресс-бары и эффекты level-up.
Для интерфейса урок такой: не пытайтесь «вычислить screen reader». Надёжного браузерного API для этого нет, и это вопрос приватности. А reduced motion - явная настройка. Её можно уважать, показать в интерфейсе и проверить на декоративных анимациях.
Мини-тест: включили настройку - переходы, автоскролл, эффекты прогресса и победы стали спокойными, а смысл экрана не потерялся.
В ProgressRPG завели issue про отдельный переключатель «уменьшить движение» в настройках аккаунта.
Предложение аккуратное: при первом открытии взять системный
prefers-reduced-motion как подсказку, но дальше хранить выбор внутри приложения и дать человеку переопределить его.Это помогает людям с вестибулярной чувствительностью, ADHD, мигренями и перегрузом от анимаций. Плюс обычный случай: пользователь может не хотеть менять всю ОС из-за одной игры, где двигаются прогресс-бары и эффекты level-up.
Для интерфейса урок такой: не пытайтесь «вычислить screen reader». Надёжного браузерного API для этого нет, и это вопрос приватности. А reduced motion - явная настройка. Её можно уважать, показать в интерфейсе и проверить на декоративных анимациях.
Мини-тест: включили настройку - переходы, автоскролл, эффекты прогресса и победы стали спокойными, а смысл экрана не потерялся.
Свежий баг в Highcharts: график закрыли, а accessibility-таймеры продолжают работать.
В issue от 30 августа описан сценарий: график с
Для зрячего пользователя экран уже перешёл дальше. А пользователь скринридера может услышать сообщение от старого графика, которого в интерфейсе больше нет. Это ложный контекст: человек пытается понять текущий экран, а ему подмешивают событие из прошлого состояния.
Что проверять:
• при размонтировании виджета очищаются все
•
• после закрытия модалки, вкладки или графика нет запоздалых озвучек;
• на это есть регрессионный тест.
Доступность ломается и от тишины, и от лишней речи. Старый компонент не должен продолжать говорить.
Источник: Highcharts issue #25117
В issue от 30 августа описан сценарий: график с
accessibility.announceNewData.enabled ставит отложенное объявление для screen reader. Потом компонент уничтожают, но два таймера не очищаются. Один позже может объявить новые данные, второй - записать текст в уже отсоединённый live-region.Для зрячего пользователя экран уже перешёл дальше. А пользователь скринридера может услышать сообщение от старого графика, которого в интерфейсе больше нет. Это ложный контекст: человек пытается понять текущий экран, а ему подмешивают событие из прошлого состояния.
Что проверять:
• при размонтировании виджета очищаются все
setTimeout/setInterval;•
aria-live не объявляет события от старого состояния;• после закрытия модалки, вкладки или графика нет запоздалых озвучек;
• на это есть регрессионный тест.
Доступность ломается и от тишины, и от лишней речи. Старый компонент не должен продолжать говорить.
Источник: Highcharts issue #25117
GitHub
Issue · highcharts/highcharts
Highcharts JS, the JavaScript charting framework. Contribute to highcharts/highcharts development by creating an account on GitHub.
Видео без дорожки субтитров — это не «потом допишем текст».
В SCORM-проекте edumints-scorm-mcp завели issue: video screen выводит
Вывод для команд: проверяйте не только кнопку Play, а весь путь — captions track, доступный переключатель субтитров, transcript для audio-only и честную синхронизацию.
В SCORM-проекте edumints-scorm-mcp завели issue: video screen выводит
<video controls>, но без <track> и WebVTT. Статическая подпись и narration_text не заменяют синхронные субтитры.Вывод для команд: проверяйте не только кнопку Play, а весь путь — captions track, доступный переключатель субтитров, transcript для audio-only и честную синхронизацию.
Видео без дорожки субтитров — это не «потом допишем текст».
Свежий сигнал из GitHub: в проекте edumints-scorm-mcp, который собирает SCORM-курсы, завели issue про video screen. Сейчас рендерер выводит обычный
Что это значит на практике: студент открывает курс, в ролике есть речь, но синхронных субтитров нет. Статическая подпись под видео или отдельный блок narration_text не заменяют субтитры: человек не видит, какая фраза звучит сейчас, где началась новая мысль, что относится к текущему кадру.
Это мешает не только глухим и слабослышащим. В шумном офисе, в метро, без наушников, на старом телефоне с плохим звуком — проблема становится той же: контент есть, но пользоваться им неудобно или невозможно.
Хороший вывод для продуктовых команд: если в интерфейсе есть обучающее видео, проверяйте не только кнопку Play. Минимальный рабочий набор —
И важная мелочь: если субтитров нет, не называйте экран «доступным» только потому, что рядом есть текст. Для пользователя важен не факт наличия текста, а возможность следить за содержанием в нужный момент.
Свежий сигнал из GitHub: в проекте edumints-scorm-mcp, который собирает SCORM-курсы, завели issue про video screen. Сейчас рендерер выводит обычный
<video controls>, но без <track> и без WebVTT-пайплайна. В документации проекта это прямо записано как fail по WCAG 1.2.2.Что это значит на практике: студент открывает курс, в ролике есть речь, но синхронных субтитров нет. Статическая подпись под видео или отдельный блок narration_text не заменяют субтитры: человек не видит, какая фраза звучит сейчас, где началась новая мысль, что относится к текущему кадру.
Это мешает не только глухим и слабослышащим. В шумном офисе, в метро, без наушников, на старом телефоне с плохим звуком — проблема становится той же: контент есть, но пользоваться им неудобно или невозможно.
Хороший вывод для продуктовых команд: если в интерфейсе есть обучающее видео, проверяйте не только кнопку Play. Минимальный рабочий набор —
<track kind="captions">, WebVTT-файл внутри пакета, доступный переключатель субтитров, отдельный transcript для аудио-only сценариев и честная документация, где синхронизация приблизительная.И важная мелочь: если субтитров нет, не называйте экран «доступным» только потому, что рядом есть текст. Для пользователя важен не факт наличия текста, а возможность следить за содержанием в нужный момент.
GitHub
WebVTT altyazı hattı (<track>) — a11y kısıt #1 / #2 · Issue #145 · kemalyy/edumints-scorm-mcp
Boşluk (kod-doğrulamalı) docs/ACCESSIBILITY-CONFORMANCE.md §3 kısıt #1: No synchronized captions or transcripts for video (WCAG 1.2.2 fail for videos with audio). _r_video emits a <video control...
Форма, которую заполняют в 3 ночи
В issue PaedsMom описали проверку формы консультации: ей могут пользоваться испуганные родители, часто одной рукой, с ребёнком на руках, на дешёвом телефоне. Часть людей ещё и с экранным диктором.
Это хороший пример, почему доступность формы - не список ARIA-атрибутов. Если шаги модального окна не переводят фокус на заголовок, клавиатура не может выбрать симптомы, ошибки не озвучиваются через live region, выбранные чипы отличаются только цветом, а анимации не уважают reduced motion - человек может просто не дойти до обращения за помощью.
Проверка для команды: пройти такой flow без мыши и глазами “как дизайнер” не считается. Пройдите его клавиатурой, VoiceOver/NVDA, крупным текстом и одной рукой. В конце должен быть не красивый wizard, а отправленная заявка и понятное состояние: что выбрано, где ошибка, что делать дальше.
В issue PaedsMom описали проверку формы консультации: ей могут пользоваться испуганные родители, часто одной рукой, с ребёнком на руках, на дешёвом телефоне. Часть людей ещё и с экранным диктором.
Это хороший пример, почему доступность формы - не список ARIA-атрибутов. Если шаги модального окна не переводят фокус на заголовок, клавиатура не может выбрать симптомы, ошибки не озвучиваются через live region, выбранные чипы отличаются только цветом, а анимации не уважают reduced motion - человек может просто не дойти до обращения за помощью.
Проверка для команды: пройти такой flow без мыши и глазами “как дизайнер” не считается. Пройдите его клавиатурой, VoiceOver/NVDA, крупным текстом и одной рукой. В конце должен быть не красивый wizard, а отправленная заявка и понятное состояние: что выбрано, где ошибка, что делать дальше.