Default Slot
How the default slot works
Section titled “How the default slot works”A <slot> element with no name attribute is the default slot. All light-DOM children that do not have a slot attribute are distributed there. You place the <slot> inside your shadow root, and the browser takes care of rendering the projected children at that position.
<my-box> <p>This paragraph is projected into the default slot.</p></my-box>class MyBox extends HTMLElement { connectedCallback() { const shadow = this.attachShadow({ mode: 'open' }); shadow.innerHTML = ` <style> :host { display: block; border: 2px solid #6366f1; padding: 1rem; border-radius: 8px; } </style> <slot><em>No content provided</em></slot> `; }}customElements.define('my-box', MyBox);Fallback content
Section titled “Fallback content”Content placed inside the <slot> element itself is the fallback. It renders only when no light-DOM children are projected into that slot. If the consumer provides children, the fallback is hidden; if they provide none, the fallback shows.
This is a zero-cost way to make a component self-documenting: the fallback text describes what the consumer is expected to supply.
Slot projection is not a copy
Section titled “Slot projection is not a copy”The light-DOM child stays in the light DOM — only its rendering position moves to the slot. The node is not cloned or transferred. For example, document.querySelector('my-box').firstChild still returns the <p> element even after it has been projected into the shadow root. Event listeners attached to the light-DOM node continue to work normally.