Unique IDs within web components #1438
Replies: 1 comment 1 reply
-
Sorry for the delay on this. Here's the outcome for anyone interested: TLDR; Web components do not need unique IDs because they are scoped to their shadow DOMs and therefore multiple IDs with the same name would not interfere with the main DOM as they do not leak out into the light DOM. Even though IDs should still be unique within their scope, using shadow DOM means that multiple elements can have the same ID as long as they are within different shadow DOMs. This encapsulation ensures that these IDs do not interfere with each other or with the main document (light DOM). Shadow DOM Scoping IDs within Shadow DOM What does this mean for us? Conclusion |
Beta Was this translation helpful? Give feedback.
-
The Problem
The Shadow DOM provides encapsulation for web components, allowing them to have their own scoped DOM subtree separate from the main document's DOM. This means that elements within the Shadow DOM can technically have the same IDs as elements outside or within other encapsulated Shadow DOMs without causing conflicts in the global scope.
However, despite this encapsulation, we've encountered warnings and issues related to duplicate IDs within Storybook. While technically the IDs within the Shadow DOM are scoped, ensuring unique IDs within our components is probably the safest approach to prevent any potential conflicts or issues, especially in scenarios where multiple instances of a component are used on the same page.
Potential solution (see Note as I'd like to try and avoid this)
In the context of Lit web components, if the same component is rendered multiple times on a page and each instance of the component includes elements with the same ID attribute, it could potentially lead to issues with document structure and accessibility.
While technically, within the Shadow DOM, elements with the same ID can coexist without causing global conflicts, it seems generally a best practice to ensure that IDs are unique within a given document to avoid unintended behaviour and to comply with web standards and accessibility guidelines.
To maintain uniqueness, we could consider dynamically generating IDs for elements within the component based on some unique identifier associated with each instance of the component. A library like this can help. This could be achieved using techniques such as concatenating a component-specific prefix with a unique identifier or generating random IDs programmatically.
Re-rendering Lit components
From my understanding, in Lit, when a component re-renders, the template is re-evaluated, but the DOM elements are not necessarily recreated from scratch. This means that DOM elements are not recreated from scratch during every render cycle, but rather updated as needed. If we're planning on using dynamic IDs based on some unique identifier helper associated with each instance of the component, these IDs will remain consistent across re-renders unless we explicitly change them within our component's logic.
Note:
I've asked the Lit team about using a single ID (without a unique name) as I'd prefer to avoid adding a UID to our components if we can avoid it as I don't believe we actually need it. From my understanding and reading here WCs are generally scoped to their own DOMs (Shadow DOM) as opposed to the light DOM (The main parent DOM). In the context of linking elements together for accessibility, the screen reader should in theory read within its own context.
Further reading:
Discord threads
Beta Was this translation helpful? Give feedback.
All reactions