I'm using Stencil to build web components and recently had a little talk with a colleague about shadowRoot
and implications. Suppose I have the following simple component with a a
tag which has the id
of link-button
. What happens in the parent HTML page if there are several components of the same kind? Is it semantically wrong to have several components with the same ID on the same HTML page, or is it alright since each shadowRoot
is a microcosm of its own and the containing HTML page is not aware of this so called, hidden, content?
@Component({
tag: 'link-button',
styleUrl: 'button.scss',
shadow: true,
})
export class LinkButton {
render() {
return <a id='link-button'></a>;
}
}
This is how this component looks during inspection. Imagine 10 of these.
Different shadow trees may contain elements with the same id since, as you said, shadow trees are essentially "microcosms".
Using the HTML Living Standard to prove this:
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. The value must not contain any ASCII whitespace.
To understand how the standard defines "tree", we turn to the DOM standard.
An object that participates in a tree has a parent, which is either null or an object, and has children...
The root of an object is itself, if its parent is null, or else it is the root of its parent. The root of a tree is any object participating in that tree whose parent is null.
The "tree" of an element consists of all its parents until it hits a "root" (and their children), and the element's children.
The standard makes a distinction between document trees and shadow trees because they have different roots:
A document tree is a node tree whose root is a document.
A shadow tree is a node tree whose root is a shadow root.
In other words, the root of a shadow tree is not the same as the root of the document, and hence they are in different trees for the sake of defining an id.
But to be thorough, we have to consider whether a document's children includes the shadow trees of its children. For that we turn to the definition of Node Tree.
It's harder to quote directly, but essentially a tree can either be a Document which contains Elements, or a DocumentFragment. Elements, meanwhile, are defined to contain either other Elements or CharacterData nodes, notably not DocumentFragments.
The final piece of the puzzle is that shadow roots are DocumentFragments, which are therefore not considered children of Documents for the sake of defining a tree.
Or to summarize: