HTMLSlots (<slot>)

The <slot> Element

The <slot> element is a placeholder inside a Shadow DOM tree that gets filled in with markup provided by whoever uses the component. It is how Web Components support "content projection" — letting a component's light-DOM children appear inside its encapsulated shadow tree, in exactly the position the component author designates.

Why Slots Exist

Once an element has a shadow root, its normal children (the "light DOM") are no longer rendered automatically — the shadow tree takes over what is displayed. Without a mechanism to reintroduce that content, encapsulation would make components far less flexible: consumers could not customize what appears inside a component. <slot> is that mechanism.

Default (Unnamed) Slot

A <slot> with no name attribute is the default slot. Any light-DOM child of the host element that is not assigned to a named slot gets projected there.

default-slot.html

HTML
<script>
  class InfoBox extends HTMLElement {
    connectedCallback() {
      const shadow = this.attachShadow({ mode: 'open' })
      shadow.innerHTML = `
        <style>
          .box { border: 1px solid #ccc; padding: 12px; border-radius: 6px; }
        </style>
        <div class="box">
          <slot>Default text if nothing is provided</slot>
        </div>
      `
    }
  }
  customElements.define('info-box', InfoBox)
</script>

<info-box>This text is projected into the default slot.</info-box>
<info-box></info-box>
First <info-box>:  a bordered box containing
                   "This text is projected into the default slot."
Second <info-box>: a bordered box containing the fallback
                   "Default text if nothing is provided"
Fallback content
Anything written directly inside a <slot> tag in the shadow tree is fallback content — it only renders when the host element supplies nothing for that slot.
Named Slots

A component often needs more than one insertion point — a header, a body, a footer. Named slots handle this: give the <slot> a{' '} name attribute in the shadow tree, then mark the corresponding light-DOM element with a matching slot attribute.

named-slots.html

HTML
<script>
  class UserCard extends HTMLElement {
    connectedCallback() {
      const shadow = this.attachShadow({ mode: 'open' })
      shadow.innerHTML = `
        <style>
          .card { border: 1px solid #ddd; border-radius: 8px; padding: 16px; }
          .card header { font-weight: bold; margin-bottom: 8px; }
          .card footer { margin-top: 8px; color: #666; }
        </style>
        <div class="card">
          <header><slot name="title">Untitled</slot></header>
          <slot>No content provided.</slot>
          <footer><slot name="meta"></slot></footer>
        </div>
      `
    }
  }
  customElements.define('user-card', UserCard)
</script>

<user-card>
  <span slot="title">Ada Lovelace</span>
  <p>Mathematician and writer, considered the first programmer.</p>
  <span slot="meta">Joined 1815</span>
</user-card>
  • Elements with slot="title" are projected into <slot name="title">.

  • Elements with slot="meta" are projected into <slot name="meta">.

  • Any remaining, un-slotted children (the <p> here) fall through to the default, unnamed <slot>.

How Slots Relate to Web Component Composition

Slots are one of three pieces that work together to build encapsulated, reusable components:

Piece

Role

<template>

Defines the inert markup blueprint used to build the shadow tree

Shadow DOM

Encapsulates that markup and its styles from the rest of the page

<slot>

Lets the encapsulated tree accept and position content supplied by the consumer

See also
The dedicated pages on <template>, Shadow DOM, and Custom Elements cover the other two pieces of this picture in depth.
Styling Slotted Content

Because projected content still logically "belongs" to the light DOM, the shadow tree's own styles do not apply to it directly. Two CSS pseudo-elements/classes exist for this:

Selector

Targets

::slotted(selector)

Projected (light-DOM) elements matching selector, from inside the shadow-tree stylesheet

:host

The custom element itself, from inside the shadow-tree stylesheet

slotted-styling.html

HTML
<style>
  ::slotted(span) {
    color: darkslateblue;
    font-weight: bold;
  }
</style>
<slot></slot>
Quick Reference
  • A <slot> only has meaning inside a shadow root — it does nothing in regular (light) DOM.

  • Unnamed <slot> catches any child without a slot attribute; named slots catch children with a matching slot="...".

  • Fallback content is written directly inside the <slot> tag and shows only when nothing is projected.

  • Style projected content from the shadow tree with ::slotted().