Are duplicate IDs allowed in separate shadow roots?
Asked Answered
W

2

24

tl;dr:

  1. Is it valid to have two elements with the same ID attribute, as long as both are under separate shadow roots?
  2. Would screen readers handle aria-labelledby correctly in such situation?

For example, consider this custom element:

(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)
})()

Would it be valid to do:

<company-logo>
  Title One.
</company-logo>

<company-logo>
  Some other title.
</company-logo>

Would this be a valid DOM, even when both <title>'s share the same ID? Would screen readers read "Title One" for the first logo, and "Some other title" for the second logo?

Washerwoman answered 7/5, 2019 at 13:6 Comment(6)
I am not sure, but my guess would be no. Te point of an ID is to be a unique identifier. If you wanted to select one of these by ID, how would you know which one was being targeted?Leola
@ChrisBarr querySelector or getElementById don't cross shadow root boundary, so that shouldn't be an issue, should it?Washerwoman
I suppose not, but still why even have the same ID anyway? it just seems like it's ripe for developer confusion at the least. Why not make the ID with a random suffix? like id="logo-title-${Math.random().toString(36).substr(2, 8)}"Leola
I'm just wondering if it's legal and handled properly. Can't find any explicit mention of this case in the spec.Washerwoman
Well I don't know either, but it can't hurt going with actually unique ID's. Also, you can try out a screenreader to see if it works - download the ChromeVox extension for Chrome, it's pretty easy to use.Leola
With CSS, IDs, scripts etc. Think of ShadowDOM as being an IFrame.... its content is scoped to a container/DOM. Only difference is that Custom Elements script can actually access the host they are in.Edmea
E
25

You can have multiple instances of the same custom element on the same page, so the inner Shadow DOM will share by design the same IDs.

As far as the standards are concerned...

  • W3C's HTML5 Rec doesn't include Shadow DOM so it not a subject for them.

  • WHATWG's HTML Living Standard states that a ID should be unique among the node tree, but doesn't precise if the flattened tree (combination of the Light DOM trees and Shadow DOM trees) is concerned. For my understanding the specs doesn't say it not valid :-)

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.

Actually it's not a problem for the browsers to deal with identical IDs.

I don't think Aria Labels can cross Shadow DOM, it should depend on browser implementation. Here again the specs says nothing on Shadow DOM.


2019 Update

As stated in Google's introduction sur Shadow DOM:

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

Indeed the fact that Shadow DOM lets you create Web Components that you can distribute and reuse, the probability that inner IDs will match other IDs of other components in the same page but developped by other developers is high and the Scoped DOM is a good answer.


2020 Update

Note the Shadow DOM / ARIA issue is still being discussed.

The future AOM (Accessibility Object Model) will permit to solve this kind of question programmatically.

You'll be able to link elements not only by id labels, but also by reference:

element.ariaLabelledByElements = [ anotherElement, someOtherElement ]

No need to deal with IDs uniqueness, and possibility to cross Shadow DOM boundaries :-) maybe someday :-(

Enclasp answered 7/5, 2019 at 14:17 Comment(5)
The browser does not enforce ID uniqueness for a reason..All vendors implemented the ID behaviour Microsoft started with ages ago.. Documentation is one thing.. practice is another. If you know what you are doing duplicate IDs can be powerful Note that behaviour is only in global scope... duplicates inside ShadowDOM do not create a NodeList, neither does a single ID create a variable with the same name. Vendors won't likely disable this global behaviour as it would break loads of (shitty) sites at Fortune 500 companies. But it is always fun to read that a developer has read the manual.Edmea
@Danny'365CSI'Engelman Actually I forgot a word: I wanted to write "it's NOT a problem for the browsers to deal with identical IDs"Enclasp
Does this remain true for shadow mode: 'open'?Currajong
@Currajong what do you mean by this?Enclasp
connexo: yes. mode: 'open' only means that the non-shadow scripting contexts are allowed to access the shadow DOM. Has no bearing on ID namespacing.Nimesh
R
0

I think that one of the specific reasons to have Shadow DOM is so that you can have multiple items with the same format and structure. That includes IDs and classes. Each Shadow DOM is like it's own little document. This has a great advantage for programers because they can repeat the Shadow element multiple times without having to generate unique IDs for the elements within the Shadow.

Raid answered 21/1, 2021 at 16:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.