shadow DOM slots
Shadow DOM supports <slot> elements, that are filled by the content from light DOM.
browser ⟩ web components ⟩ implement ⟩ shadow DOM ⟩ slots
if those descendants include a
<slot>element, then the regular light DOM children of the host element are displayed as if they were children of that<slot>(they do not actually become part of the shadow DOM), replacing any shadow DOM content in the slot.if shadow DOM does not include a
<slot>, then any light DOM content of the host is never displayed.if shadow DOM has a
<slot>, but the shadow host has no light DOM children, then the shadow DOM content of the slot is displayed as a default.
Fallback Content
Default Slot
Code Example
<user-card>
<!-- ⭐️ light DOM: slotted elements -->
<!-- ⭐️ only top-level children may have [slot="…"] attribute❗️ -->
<span slot="username">John Smith</span>
<span slot="birthday">2001.01.01</span>
</user-card>class UserCard extends HTMLElement {
// connected to document
connectedCallback() {
// attach shadow root
const root = this.attachShadow({mode: 'open'});
// ⭐️ named slots in shadow dom tree
root.innerHTML = `
<style>
::slotted(*) {
border: 1px solid black;
padding: 0 4px;
display: inline-block;
margin: 2px auto;
background-color: hsla(60, 80%, 50%, 0.4);
}
::slotted(:hover) {
background-color: hsla(90, 80%, 50%, 0.8);
}
</style>
<div>Name:
<slot name="username"></slot>
</div>
<div>Birthday:
<slot name="birthday"></slot>
</div>
`;
}
}
customElements.define('user-card', UserCard);<user-card>
#shadow-root
<div>Name:
<slot name="username">
<!-- ⭐️ slotted element is inserted into the slot -->
<span slot="username">John Smith</span>
</slot>
</div>
<div>Birthday:
<slot name="birthday">
<span slot="birthday">01.01.2001</span>
</slot>
</div>
</user-card><script>
customElements.define('user-card', class extends HTMLElement {
connectedCallback() {
this.attachShadow({mode: 'open'});
// ⭐️ shadow DOM:v2 named slots and 1 default slot
this.shadowRoot.innerHTML = `
<div>Name:
<slot name="username"></slot>
</div>
<div>Birthday:
<slot name="birthday"></slot>
</div>
<fieldset>
<legend>Other information</legend>
<slot></slot> <!-- ⭐️ default slot -->
</fieldset>
`;
}
});
</script>
<user-card>
<!-- ⭐️ light DOM -->
<!-- ⭐️ elements with [slot="..."] go to named <slot> -->
<span slot="username">John Smith</span>
<span slot="birthday">01.01.2001</span>
<!-- ⭐️ other elements go to default slot -->
<div>I like to swim.</div>
<div>...And play volleyball too!</div>
</user-card><div>Name:
<slot name="username">
<!-- ⭐️ fallback content -->
Anonymous
</slot>
</div>Named Slots
Flattened DOM
the flattened DOM exists only for rendering and event-handling purposes. It’s kind of “virtual”. That’s how things are shown. But the nodes in the document are actually not moved around! 👉 See "flattened DOM" tab above.
The process of rendering slotted elements inside their slots is called “composition”.
Last updated
Was this helpful?