Пользовательские элементы и доступность

Я хотел бы реализовать виджет списка, используя текущие спецификации веб-компонентов. Более того, результирующий список должен соответствовать стандарту ARIA. Создание экземпляра виджета списка должно быть таким же простым, как:

<x-listbox>
    <x-option>Option 1</x-option>
    <x-option>Option 2</x-option>
</x-listbox>

В целях чистоты и инкапсуляции все остальное должно отображаться в теневом доме. Для реализации этого виджета регистрируются два пользовательских элемента, <x-listbox> и <x-option>. Элемент верхнего уровня теневого дома <x-listbox> — это <div>, который содержит атрибуты role=listbox и aria-activedescendent для доступности (мне не нужны эти атрибуты в элементе <x-listbox>, потому что они являются деталями реализации).

Чтобы aria-activedescendent работал, нужны идентификаторы элементов option. Помещение id непосредственно в элементы <x-option> не сработает по двум причинам: во-первых, это загрязнит пространство имен id документа, в котором используется виджет списка. Во-вторых, что еще более важно, идентификаторы не работают через теневые границы (что является одной из целей теневого дома), поэтому идентификаторы опций должны жить в том же теневом доме, что и <div> с атрибутом aria-activedescendent.

Решением для этого было бы окружить каждый <x-option>, отображаемый как контент внутри теневого дома <x-listbox>, другим <div> (принадлежащим этому теневому дому), на который можно поместить идентификатор.

Мой вопрос: правильный ли это путь и как это реализовать с помощью пользовательского элемента и веб-API теневого дома?


person Marc    schedule 13.05.2014    source источник


Ответы (2)


Возможно, вам лучше реализовать это, создав элемент select (используя JavaScript). Это должно гарантировать, что программы чтения с экрана правильно распознают это как ввод для выбора значения/значений из списка.

Добавьте элемент select, подобный этому, под элементом <x-listbox>:

<select class="only-screenreader">
   <option>Option 1</option>
   <option>Option 2</option>
</select>

Затем добавьте aria-hidden="true" к своему пользовательскому элементу <x-listbox>.

Наконец, примените CSS, чтобы сделать элемент выбора программы чтения с экрана невидимым.

.only-screenreader {
   position:absolute;
   left:-10000px;
   top:auto;
   width:1px;
   height:1px;
   overflow:hidden;
}

Это мой подход, но, возможно, есть лучший.

person idmean    schedule 17.08.2014
comment
Хотя это будет работать с точки зрения доступности, это противоречит моим целям инкапсуляции (поскольку элемент select, который не является частью предоставленного HTML, появится в легкой DOM). Во-вторых, если бы я попытался сделать то же самое с более сложным виджетом (например, со списком, параметры которого содержат больше, чем текст), мне пришлось бы заменить элемент select сделанным на заказ виджетом, соответствующим арии, что просто означает, что я бы удвоить мой x-listbox. - person Marc; 27.08.2014

В представленной разметке x-option находится в светлой, а не в теневой модели DOM, поэтому на нее можно ссылаться по идентификатору. Чтобы не загрязнять пространство имен id, я генерирую случайный id, который устанавливается при загрузке компонента, но может быть заменен. Таким образом, я могу ссылаться на элемент по идентификатору, независимо от того, установил ли пользователь компонента идентификатор для него. Оборачивать каждую опцию в div кажется ненужным и может вызвать проблемы. Кроме того, если параметры находятся в <slot />, это просто невозможно.

person mrtnmgs    schedule 25.05.2021