Currently, the only way to construct a ShadowRoot
is via the imperative attachShadow
API.
Has any consideration been given to providing a declarative Shadow DOM tag?
In order to support Web Component server side rendering, there has to be a way to serialize their contents in a way that can be displayed before JS is initialized. This approach is possible with React components and CSS module implementations. But it would be great if all these CSS module implementations could just be using shadow in the future.
<style>
.btn {
color: blue;
}
</style>
<button class="btn">Blue Button</button>
<shadow-root mode="open">
<style>
.btn {
color: red;
}
</style>
<button class="btn">Red Button</button>
</shadow-root>
Ironic polyfill implemented via Custom Elements.
<script>
class ShadowRootElement extends HTMLElement {
constructor() {
super();
this.root = this.attachShadow({mode: this.getAttribute('mode')});
}
connectedCallback() {
for (const child of Array.from(this.childNodes)) {
this.root.appendChild(child);
}
}
}
customElements.define('shadow-root', ShadowRootElement);
</script>
Obviously this polyfill has a number of problems and would be better served with a native implementation that could run before scripts are loaded.
Now that <style scoped>
has been removed, this provides that same declarative mechanism.
Also related, I’ve found hints of HTMLShadowElement
in Shadow DOM v0, however it don’t think it could ever be initialized via a tag name.