Named Slots
Named slots
Section titled “Named slots”A named slot is a <slot> element with a name attribute in the shadow tree, paired with a slot attribute on a light-DOM child. The browser matches them by name and renders each light-DOM child at its corresponding insertion point. Using multiple named slots lets a single component expose several distinct content areas — a common pattern for card, dialog, and layout components.
<my-card> <span slot="header">Card Title</span> <p slot="body">Card body text here.</p></my-card>class MyCard extends HTMLElement { connectedCallback() { const shadow = this.attachShadow({ mode: 'open' }); shadow.innerHTML = ` <style>...</style> <div class="card"> <header><slot name="header">Untitled</slot></header> <section><slot name="body">No body.</slot></section> </div> `; }}customElements.define('my-card', MyCard);Unmatched slot attributes
Section titled “Unmatched slot attributes”Light-DOM children with a slot attribute that does not match any named slot in the shadow tree are silently skipped — they are not rendered anywhere. This means typos in slot names cause invisible content, so double-check your slot names when debugging missing content.
Default and named together
Section titled “Default and named together”An element can have both named slots and a default slot at the same time. Named-slot children are distributed to their matching named slots, while any remaining children without a slot attribute fall through to the default slot. This makes it easy to build components that have structured sections (header, footer) plus a freeform content area.
Trade-offs
Section titled “Trade-offs”| Option | Benefit | Cost |
|---|---|---|
| Multiple named slots | Lets consumers compose the layout flexibly — great for multi-part components like cards or dialogs | Adds a learning curve — consumers must know the exact slot names, and a typo makes content disappear silently |
| A single slot name (default slot only) | Easy to learn, no chance of a slot-name typo | Limits your ability to lay out multiple separate content areas |
Common mistakes
Section titled “Common mistakes”- Mistyping a
slotattribute so it doesn’t match any named slot in the shadow tree — that content is silently never rendered, with no error at all. Always double-check the names match. - Expecting to style every descendant of content projected into a named slot from the shadow root —
::slotted()only selects the top-level projected element, it doesn’t reach into its own descendants. - Forgetting fallback content for a named slot that might go unfilled — leaves the UI empty with no explanation when a consumer forgets to fill that slot.
💡 Real-world examples
Shoelace uses named slots extensively in its component API design — like the
prefix/suffixslots in<sl-input>or theiconslot in<sl-button>— so consumers can inject icons or extra content flexibly.Lit recommends the named-slots pattern for building composable components, such as a layout component with separate
header,content, andfooterslots.