🔸slotted nodes
a.k.a distributed nodes.
web ⟩ component ⟩ slot ⟩ slotted nodes
Styling in Shadow DOM ⟩ ::slotted()
📗 JS.info ⟩ Styling slotted content
👉 Styling in Shadow DOM - :host, :host(), :host-context(), ::slotted()
Only custom element's top-level children (in the light DOM) may have
[slot]attribute❗️ 👉 See "light DOM" tab in example code in Using Slots.::slotted() only select slotted element itself, not its descendants (content)❗️
Slotted Contents
slotted content come from light DOM, they use document styles❗️
shadow DOM styles do not affect slotted content❗️
::slotted() only select slotted element itself, not its descendants (content)❗️
::slotted() can't go inside light DOM, for example: ::slotted(div) p is invalid❗️
::slotted() can't be used in .querySelector()❗️
在下面的範例碼中,我們分別在外部及內部 CSS 對 <span> 元素做「粗體」與「紅色」格式設定,對於插入 shadow DOM<slot> 的 <span> 而言,只有外部的「粗體」設定有效 (👉 see: "codepen" tab below)。 💾 replit
<!-- ⭐️ document (outer) styles -->
<style>
span {
font-weight: bold
}
</style>
<!-- ⭐️ custom element -->
<user-card>
<!-- ⭐️ slotted element -->
<div slot="username">
<!--
⭐️ slotted content is affected by document (outer) styles,
not by local (shadow DOM) styles❗️
-->
<span>John Smith</span>
</div>
</user-card>
<script>
customElements.define('user-card', class extends HTMLElement {
connectedCallback() {
this.attachShadow({mode: 'open'});
// ⭐️ shadow tree (with named <slot>)
// 1. slotted elements come from light DOM, they use document styles.
// 2. local styles do not affect slotted content.
this.shadowRoot.innerHTML = `
<style>
span { background: red; }
</style>
Name: <slot name="username"></slot>
`;
}
});
</script>Styling Slotted Content
use document (outer) styles (in light DOM).
style <slot> (in shadow DOM) and rely on CSS inheritance.
use ::slotted(«selector») in shadow DOM.
<!-- ⭐️ document (outer) styles -->
<style>
span {
font-weight: bold
}
/* ⭐️ select <span> in slotted <p> element */
p[slot] span {
background: hsl(90, 90%, 80%); /* light green */
padding: 0 8px;
}
</style>
<!-- ⭐️ custom element -->
<user-card>
<!-- ⭐️ slotted element -->
<div slot="username">
<!--
⭐️ slotted content is affected by document (outer) styles,
not by local (shadow DOM) styles❗️
-->
<span>John Smith</span>
</div>
</user-card>
<user-card>
<span slot="username">Jane Smith</span>
</user-card>
<user-card>
<p slot="username">
<span>Doctor Who</span>
</p>
</user-card>
<script>
customElements.define('user-card', class extends HTMLElement {
connectedCallback() {
this.attachShadow({mode: 'open'});
// ⭐️ shadow tree (with named <slot>)
// 1. slotted elements come from light DOM, they use document styles.
// 2. local styles do not affect slotted content.
// 3. ::slotted() only select slotted element itself, not its descendants❗️
this.shadowRoot.innerHTML = `
<style>
:host {
border: 1px solid black;
margin: 4px;
padding: 4px;
display: inline-block;
box-shadow:
0 4px 8px 0 rgba(0, 0, 0, 0.4),
0 6px 20px 0 rgba(0, 0, 0, 0.19);
}
:host(:hover) {
box-shadow:
0 2px 4px 0 rgba(0, 0, 0, 0.6),
0 3px 10px 0 rgba(0, 0, 0, 0.35);
}
::slotted(*) {
border: 1px solid black;
}
::slotted(span) {
background: pink;
padding: 0 6px;
}
::slotted(div) {
padding: 0 6px;
background: hsl(225, 80%, 90%);
}
</style>
Name: <slot name="username"></slot>
`;
}
});
</script><style>
/* ⭐️ 2. set css var with custom value */
user-card {
--user-card-field-color: green;
}
</style>
<template id="tmpl">
<style>
/* ⭐️ 1. use css var with default value */
.field {
color: var(--user-card-field-color, black);
}
</style>
<div class="field">Name: <slot name="username"></slot></div>
<div class="field">Birthday: <slot name="birthday"></slot></div>
</template>Last updated
Was this helpful?