单独的影子根中是否允许重复 ID?

Are duplicate IDs allowed in separate shadow roots?

tl;博士:

  1. 具有相同 ID 属性的两个元素是否有效,只要它们都在不同的影子根下?
  2. 屏幕阅读器会在这种情况下正确处理 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",为第二个徽标读取 "Some other title" 吗?

您可以在同一页面上拥有同一自定义元素的多个实例,因此内部阴影 DOM 将按设计共享相同的 ID。

就标准而言...

  • W3C's HTML5 Rec 不包括 Shadow DOM 所以它不是他们的主题。

  • WHATWG's HTML Living Standard 声明 ID 在节点树中应该是唯一的,但如果扁平树(Light DOM 树和 Shadow DOM树)有关。根据我的理解,规格并没有说它无效:-)

When specified on HTML elements, the id attribute value must be unique amongst all the IDs in the element's tree and must contain at least one character.

其实浏览器处理相同的ID不是问题。

我不认为 Aria Labels 可以跨越 Shadow DOM,这应该取决于浏览器的实现。这里又是 the specs says nothing 影子 DOM.


2019更新

正如 Google 的介绍 sur Shadow DOM:

Scoped DOM means you can use simple CSS selectors, more generic id/class names, and not worry about naming conflicts.

事实上,Shadow DOM 允许您创建可以分发和重用的 Web 组件,内部 ID 与同一页面中其他组件的其他 ID 匹配但由其他开发人员开发的可能性很高Scoped DOM 是一个很好的答案。


2020年更新

注意阴影 DOM / ARIA 问题仍然是 being discussed

未来 AOM(无障碍对象模型)将允许 to solve this kind of question 以编程方式。

您不仅可以通过 id 标签,还可以通过引用 link 元素:

element.ariaLabelledByElements = [ anotherElement, someOtherElement ]

无需处理 ID 的唯一性,以及跨越 Shadow DOM 边界的可能性 :-) 也许有一天 :-(

我认为拥有 Shadow DOM 的具体原因之一是您可以拥有多个具有相同格式和结构的项目。这包括 ID 和 类。每个 Shadow DOM 就像它自己的小文档。这对程序员来说有很大的优势,因为他们可以多次重复 Shadow 元素,而不必为 Shadow 中的元素生成唯一 ID。