I'm trying to use the shadow DOM without any framework that abstracts it, mostly in order to learn its intricacies. I am using the webcomponents.js polyfills, so it works cross-browser.
I've managed to create a custom element, and set its shadow DOM, but for some reason the <content></content>
tag isn't transcluding the expected content.
I expect this example to render as
Shadow DOM
Hello world
More Shadow
But it renders as
Shadow DOM
More Shadow
What am I missing here?
<script src="webcomponents-lite.min.js"></script>
<test-component>
<div>Hello world</div>
</test-component>
<template id="test-component">
<div>Shadow DOM</div>
<content></content>
<div>More shadow</div>
</template>
<script>
class TestComponent extends HTMLElement {
constructor() {
super();
var shadow = super.attachShadow({ mode: 'open' });
var template = document.getElementById('test-component');
var clone = document.importNode(template.content, true);
shadow.appendChild(clone);
}
}
customElements.define('test-component', TestComponent);
</script>
(The example is complete, and can be run as an entire HTML file, provided you have webcomponents-lite.min.js available, or can be run without the .js file in supported browsers)
As noted in a comment above, you need to use the slot
element and slot
attribute instead.
Here’s exactly the same code as above, but implemented using the slot
element and attribute:
<test-component>
<div slot=middle>Hello world</div>
</test-component>
<template id="test-component">
<div>Shadow DOM</div>
<slot name=middle></slot>
<div>More shadow</div>
</template>
<script>
class TestComponent extends HTMLElement {
constructor() {
super();
var shadow = super.attachShadow({ mode: 'open' });
var template = document.getElementById('test-component');
var clone = document.importNode(template.content, true);
shadow.appendChild(clone);
}
}
customElements.define('test-component', TestComponent);
</script>