我过去的理解是,列表项
<li>
标签必须是 <ul>
、<ol>
或 <menu>
标签的直接子代。
但我最近一直在使用 Web 组件和自主自定义元素。我读到,对于自主自定义元素,内容模型是透明的。请参阅https://html.spec.whatwg.org/multipage/custom-elements.html#custom-elements-core-concepts
我想要一个自主自定义元素
<my-list>
,其 ShadowDOM 中有一个 <ul>
(或其他有效父元素之一,例如 ol
和 menu
),以及第二个自主自定义元素 <my-list-item>
ShadowDOM 中有一个 <li>
。 (参见下面的“示例”。)
为什么?几个原因:
<li>
除了 <slot>
根据 HTML 5 规范和辅助功能指南,类似下面这个示例的内容是有效还是无效?
注意:我使用
<template shadowrootmode="open">
(参见此处 https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template#shadowrootmode )使我的示例更加独立。在我的实际代码中,我使用 Lit 框架,它以编程方式创建 ShadowDOM。
示例:
<my-list role="presentation">
<template shadowrootmode="open">
<ul>
<slot />
</ul>
</template>
<my-list-item role="presentation">
<template shadowrootmode="open">
<li>
<slot />
</li>
</template>
My text here
</my-list-item>
</my-list>
我认为这可能有效的另一个原因是我看到 axe-core 有一个看起来相似的单元测试:
https://github.com/dequelabs/axe-core/blob/develop/test/checks/lists/only-listitems.js#L224-L232
it('should return false in a shadow DOM pass', () => {
const node = document.createElement('div');
node.innerHTML = '<li>My list item </li>';
const shadow = node.attachShadow({ mode: 'open' });
shadow.innerHTML = '<ul><slot></slot></ul>';
const checkArgs = checkSetup(node, 'ul');
assert.isFalse(checkEvaluate.apply(checkContext, checkArgs));
});
但看起来这是 axe-core 中的特定模式/选项,而不是默认行为?
在理论上,你所说的都是有道理的。这意味着以下事情是正确的:
因此,这意味着您应该被允许创建完全自定义的列表。所以,这应该有效:
<script>
class MyList extends HTMLElement {
constructor() {
super();
this.attachShadow({mode: 'open'});
this.shadowRoot.innerHTML = `
<ul aria-label="Custom List">
<slot></slot>
</ul>
`;
}
}
class MyListItem extends HTMLElement {
constructor() {
super();
this.attachShadow({mode: 'open'});
this.shadowRoot.innerHTML = `
<li>
<slot></slot>
</li>
`;
}
}
customElements.define('my-list', MyList);
customElements.define('my-list-item', MyListItem);
</script>
<my-list aria-label="Custom Wrapper">
<my-list-item>Item 1</my-list-item>
<my-list-item>Item 2</my-list-item>
</my-list>
在这种情况下,
<ul>
的影子根与 <li>
元素的影子根不同。对于上述定义,浏览器最终会生成以下可访问性树(来自 Chrome 浏览器):
因此,根据规范,浏览器正确生成了大多数工具应该看到的可访问性树。我最好的猜测是,
axe-core
在此给定测试中依赖相同的规格。但在实践中,情况有所不同。
<ul>
和 <ol>
的规范仍然明确限制它们仅具有 <li>
、<script>
和 <template>
。 (将来应该解决这个问题)。因此,根据规范,您最好在完全不同的 Shadow DOM 中的自定义列表中拥有自定义列表元素,但实际上,可访问性仍然会受到影响。如果可能,最好依赖经典的
ul > li
或 ol > li
层次结构。