自定义元素和可访问性

时间:2014-05-13 06:38:11

标签: web-component wai-aria shadow-dom

我想使用当前的网络组件规范来实现一个列表框小部件。此外,生成的列表框应符合ARIA标准。实例化列表框小部件应该简单如下:

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

为了清洁和封装,其他一切都应该用阴影dom渲染。要实现此窗口小部件,需要注册两个自定义元素<x-listbox><x-option><x-listbox>影子dom的顶级元素是<div>,其中包含role=listboxaria-activedescendent属性以便访问(我不想要这些属性)在<x-listbox>元素上,因为它们是实现细节。)

为了使aria-activedescendent起作用,需要选项元素的ID。将id直接放在<x-option>元素上的原因有两个:第一,它会污染使用列表框小部件的文档的id命名空间。其次,更重要的是,id不能跨越阴影边界(这是阴影dom的一个目的),因此选项的id必须与<div>一样生成与{{1}相同的阴影dom属性。

对此的一个解决方案是围绕aria-activedescendent的阴影dom内的每个<x-option>包围另一个<x-listbox>(属于该阴影dom),其中id可以放。

我的问题是:这是正确的方法吗?如何使用自定义元素和影子dom web apis实现这一点?

2 个答案:

答案 0 :(得分:1)

您可能应该通过创建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;
}

这是我的方法,但也许有更好的方法。

答案 1 :(得分:0)

在提供的标记中,x-option 位于 light DOM 中,而不是 shadow DOM 中,因此可以通过 id 引用它。为了避免污染 id 命名空间,我生成了一个随机 id,该 id 在组件加载时设置但可以替换。这样我就可以通过 id 引用元素,无论组件用户是否在其上设置了 id。 将每个选项包装在 div 中似乎没有必要,而且可能会导致问题。此外,如果选项位于 <slot /> 中,则根本不可能。