单独的卷影根中是否允许重复ID?
tl;dr:
- 只要两个元素都位于不同的卷影根目录下,具有相同ID属性的两个元素是否有效?
- 在这种情况下,屏幕阅读器是否能正确处理
aria-labelledby
?
例如,考虑以下自定义元素:
(function () {
let template = document.createElement('template')
template.innerHTML = `
<svg viewBox="0 0 206 74"
fill="none"
xmlns="http://www.w3.org/2000/svg"
role="img"
aria-labelledby="logo-title">
<title id="logo-title"><slot>Logo of Some Company.</slot></title>
<path d="..." fill="..."/>
</svg>
`
class Logo extends HTMLElement {
constructor () {
super()
let shadowRoot = this.attachShadow({mode: 'open'})
shadowRoot.appendChild(template.content.cloneNode(true))
}
}
customElements.define('company-logo', Logo)
})()
这样做是否有效:
<company-logo>
Title One.
</company-logo>
<company-logo>
Some other title.
</company-logo>
这是否是有效的DOM,即使这两个<title>
共享相同的ID?屏幕阅读器是否会为第一个徽标读取"Title One",为第二个徽标读取"其他标题"?
解决方案
您可以在同一页上拥有同一自定义元素的多个实例,因此内部阴影DOM将通过设计相同的ID来共享。
就标准而言.
W3C's HTML5 Rec不包括卷影DOM,因此不是他们的主题。
WHATWG's HTML Living Standard声明ID在节点树中应该是唯一的,但不精确地说明是否涉及扁平树(Light DOM树和Shadow DOM树的组合)。据我理解,规格并没有说它无效:-)
当在HTML元素上指定时,id属性值在元素树中的所有ID中必须是唯一的,并且必须至少包含一个字符。
实际上,浏览器处理相同的ID不是问题。
我不认为Aria标签可以跨越Shadow DOM,它应该取决于浏览器的实现。此处再次the specs says nothing位于阴影DOM上。
2019更新
如Google简介中所述,sur Shadow DOM:
事实上,Shadow DOM允许您创建可以分发和重用的Web组件,内部ID与同一页面中由其他开发人员开发的其他组件的其他ID匹配的可能性很高,作用域DOM是一个很好的答案。作用域DOM意味着您可以使用简单的CSS选择器、更通用的ID/类名,而不必担心命名冲突。
2020更新
注意:影子DOM/ARIA问题仍然being discussed。
将来的AOM(辅助功能对象模型)将以编程方式允许to solve this kind of question。
您不仅可以通过id
标签链接元素,还可以通过引用链接元素:
element.ariaLabelledByElements = [ anotherElement, someOtherElement ]
不需要处理ID的唯一性,也不需要跨越影子DOM边界的可能性:-)也许有一天:-(
相关文章