#html #accessibility #axe
Вопрос:
На нашей странице есть несколько вкладок со следующей структурой:
<ul role="tablist">
<li>
<div role="tab" tabindex="0" aria-selected="true" aria-controls="id1">First tab content...</div>
</li>
<li>
<div role="tab">Second tab content...</div>
</li>
</ul>
Это приводит к двум нарушениям при выполнении тестов доступности Axe, а именно:
<li> elements must be contained in a <ul> or <ol>
, и Certain ARIA roles must contain particular children
(также обратное, что некоторым дочерним элементам нужны определенные родительские роли).
Я понимаю, что первое нарушение связано с tablist
ролью, означающей, что <ul>
больше не рассматривается как <ul>
. Я не понимаю второго нарушения, поскольку спецификация не устанавливает, что элементы с role="tab"
являются непосредственными дочерними элементами tablist
.
Одним из возможных исправлений, которое предотвращает эти нарушения, было бы перейти role="tab"
к <li>
элементам. Проблема, однако, заключается в другом нарушении: Nested interactive controls are not announced by screen readers
, предположительно, из-за того, что содержащееся <div>
в нем является фокусируемым. Изменение этого на внешний <li>
потребует целого ряда изменений js и css, поэтому это не простое исправление.
В какой степени это действительно нуждается в исправлении и каков наилучший подход?
Ответ №1:
Ax неверен. Спецификация для tab
роли гласит:
Авторы ДОЛЖНЫ убедиться
tab
, что элементы с ролью содержатся в элементе с ролью или принадлежатtablist
ему.
Акцент мой. Обратите внимание, что это говорит о том, что a tab
должно содержаться в a tablist
. Содержащийся в означает не прямого потомка, а скорее потомка.
Это еще больше подчеркивается, если вы посмотрите на следующую фразу или принадлежащий. «Принадлежит» имеет определение:
«Принадлежащий элемент» — это любой DOM-потомок элемента, любой элемент, указанный как дочерний через
aria-owns
, или любой DOM-потомок принадлежащего дочернего элемента.
Итак, еще раз, пока tab
является потомком a tablist
(дочерний элемент, внук, правнук и т. Д.), То технически это допустимо, а ax неверно.
Теперь определение «owned» дает вам представление о том, как вы можете обойти ошибку axe, если нарушение вас беспокоит. Добавьте aria-owns
в свой <ul>
и укажите на tab
элементы (ваши <div>
). Ваш исходный код будет проходить axe следующим образом:
<ul role="tablist" aria-owns="foo1 foo2">
<li>
<div id="foo1" role="tab" tabindex="0" aria-selected="true" aria-controls="id1">First tab content...</div>
</li>
<li>
<div id="foo2" role="tab">Second tab content...</div>
</li>
</ul>
У вас все еще есть проблема с <li>
не содержащимся в a <ul>
. @graham рассмотрел эту часть. И я также согласен с @graham в том, что вы должны следовать практике разработки шаблона проектирования вкладок.
Комментарии:
1. Главный совет
aria-owns
, поскольку это отличное решение, чтобы заставить Axe перестать жаловаться и не выполнять с ним циклические циклы! 1
Ответ №2:
Ответ с вашей текущей настройкой заключается в удалении семантического значения из <li>
.
<ul role="tablist">
<li role="none presentation">
<div role="tab" tabindex="0" aria-selected="true" aria-controls="id1">First tab content...</div>
</li>
<li role="none presentation">
<div role="tab">Second tab content...</div>
</li>
</ul>
role="none presentation"
удаляет все семантическое значение из <li>
(так что думайте об этом как <div>
сейчас).
Было бы предпочтительнее переместить все «на один уровень», чтобы сохранить порядок в DOM, поэтому лучшим решением может быть:
<ul role="tablist">
<li role="tab" tabindex="0" aria-selected="true" aria-controls="id1">
First tab content...
</li>
<li role="tab">
Second tab content...
</li>
</ul>
Это будет работать, поскольку теперь вы изменили семантическое значение как the <ul>
, так и the <li>
, хотя для этого может потребоваться небольшая корректировка CSS.
Также Axe иногда может жаловаться на первый пример, даже если он действителен, во втором примере не будет жалоб от автоматических контролеров.
В качестве альтернативы вы можете рассмотреть использование <button>
элементов для создания вкладок, см. Пример tabs на W3 о том, как это структурировать.
Преимущество в том, что click
обработчик можно использовать как для взаимодействия с мышью, так и с клавиатурой, потому что вы используете <button>
.