Действия по воспроизведению проблемы:
Откройте ссылку: https://nvda-test.w3spaces.com/button-accessibility-label.html Две кнопки. Эта страница содержит две кнопки, внутри каждой из которых находится фокусируемый значок. Атрибуты ARIA. Первая кнопка имеет атрибут aria-label или атрибут aria-labeledby, а вторая кнопка не имеет ни того, ни другого. Поведение NVDA: при использовании программы чтения с экрана, такой как NVDA, фокусировка на значке внутри первой кнопки (той, которая имеет aria-label или aria-labeledby) и нажатие Enter или Space приведет к возврату фокуса обратно на саму кнопку. Эта проблема не возникает со второй кнопкой (без атрибутов ARIA). Вариант использования проекта:
В моем проекте у меня есть кнопка со значком закрытия внутри. В идеале, если выделить значок закрытия и нажать Enter/Пробел, кнопка должна быть удалена со страницы. Это работает, как и ожидалось, без NVDA, но упомянутая выше проблема возникает, когда NVDA включена. Удаление атрибута aria-labeledby из кнопки устраняет эту проблему, но оно необходимо для решения других проблем доступности и, следовательно, не может быть удалено.
Я хочу, чтобы фокус не возвращался к кнопке при нажатии Enter/Пробела на значке внутри кнопки, сохраняя при этом атрибут aria-label или aria-labeledby на кнопке для обеспечения доступности.
Проблема не связана с ARIA и не характерна только для NVDA. Это также происходит с Jaws, независимо от того, есть ли на кнопке метка.
ЕСЛИ мы посмотрим на ваш код:
<button class = "w3-btn w3-orange w3-xlarge" aria-label = "home">Button<i tabindex = "0" class = "w3-margin-left fa fa-home"></i></button>
На самом деле у вас есть вложенная проблема с фокусом.
Кнопка естественным образом является фокусируемой, и, добавив tabindex=0 к элементу <i>
, вы создаете второй фокусируемый элемент внутри кнопки.
Если вы используете табуляцию для навигации по странице, вы заметите, что у вас есть две позиции табуляции: одна для кнопки, а другая специально для вашего значка.
Это антишаблон доступности и, возможно, даже антишаблон дизайна пользовательского интерфейса. Этого следует избегать любой ценой. Возникает несколько вопросов/проблем:
Это выходит далеко за рамки доступности программ чтения с экрана.
На два последних вопроса ответ может быть и да, и нет, но не таким, как вы ожидаете. Его трудно контролировать в любых ситуациях, поэтому его лучше избегать.
По первому вопросу каждый фокусируемый элемент должен иметь свое собственное доступное имя, достаточно понятное и отличающееся от других, чтобы пользователь программы чтения с экрана точно знал, для чего предназначен этот элемент/что он делает. В вашем коде значок не имеет собственного доступного имени. Таким образом, программа чтения с экрана не знает, что сказать/показать на дисплее Брайля, это неопределенное поведение. Большинство (если не все) программ чтения с экрана пытаются найти текст за пределами элемента и в конечном итоге получают то же доступное имя, что и кнопка. Это создает путаницу, поскольку одно и то же появляется дважды.
Решение обычно очень простое: удалите tabindex=0 из <i>
, и проблема должна исчезнуть.
Однако если нажатие на значок вызывает другое действие, чем нажатие кнопки, вместо этого вам следует:
Действия кнопки и значка закрытия различны, поэтому то, что я говорю в конце своего ответа, применимо. Для близкого действия я бы рекомендовал вообще не делать его фокусируемым и реагировать на клавишу удаления на самой вкладке.
Проблема была решена путем изменения NVDA с «Режима просмотра» на «Режим фокусировки». Выяснилось, что @keydown на пробел/ввод не срабатывает, потому что NVDA перехватывает клавиши, если он находится в режиме просмотра, что нормально. При переключении в режим фокусировки (вставка + пробел услышит звук «пишущей машинки») код должен пройти и фокус не переключается обратно на кнопку
Я реализовал логику
@keydown
для значка закрытия. Когда значок закрытия находится в фокусе и нажата любая из клавиш Enter, Space, Delete или Escape, кнопка удаляется (работает, как и ожидалось, без NVDA). Однако, если NVDA включена и кнопка все еще имеет атрибут aria-label или aria-labeledby, проблема возникает при нажатии Enter или пробела. Событие @keydown запускается при нажатии кнопки «Delete» или «Escape» (как и ожидалось), но не при нажатии «Enter» или «Пробел» (при включенном NVDA) — вместо этого фокус возвращается на кнопку. Также я написал арию-описание к иконе, которую тоже читают.