<slot>

Zuletzt aktualisiert am 6. Februar 2026

Das <slot>-Element ist ein Platzhalter innerhalb von Web Components, der von außen mit Inhalten befüllt werden kann. Stell dir einen Slot wie ein “Loch” in einem Template vor: Du definierst die Komponente mit ihrer Struktur und ihrem Styling, und die konkreten Inhalte werden erst bei der Verwendung eingesetzt. Mit Named Slots kannst du mehrere Einfügepunkte in einer Komponente definieren, und Fallback-Content zwischen den <slot>-Tags sorgt dafür, dass auch ohne zugewiesenen Inhalt etwas Sinnvolles angezeigt wird.

Grundlagen

Das <slot>-Element funktioniert ausschließlich innerhalb des Shadow DOM einer Web Component. Außerhalb des Shadow DOM hat es keine Wirkung. Die Grundidee: Du baust ein Custom Element mit attachShadow(), platzierst darin ein oder mehrere <slot>-Elemente, und der Browser fügt die Kindelemente der Komponente an den richtigen Stellen ein.

  • <slot> funktioniert nur innerhalb des Shadow DOM, außerhalb wird es ignoriert
  • Der Default Slot (ohne name-Attribut) fängt allen Inhalt auf, der keinem Named Slot zugewiesen ist
  • Named Slots werden über das name-Attribut auf dem <slot> definiert und über das slot-Attribut am Kindelement zugewiesen
  • Fallback-Content zwischen den <slot>-Tags wird angezeigt, wenn kein Inhalt von außen zugewiesen wird
  • Das slotchange-Event feuert, wenn sich die zugewiesenen Knoten eines Slots ändern
  • Mehrere Elemente können demselben Named Slot zugewiesen werden, sie werden alle dort eingefügt
  • Slots verändern den DOM nicht wirklich: der Browser “projiziert” die Inhalte visuell an die richtige Stelle (sogenanntes “flattened tree”)

Syntax

Grundsyntax
<script>
  class SimpleCard extends HTMLElement {
    constructor() {
      super();
      this.attachShadow({ mode: "open" });
      this.shadowRoot.innerHTML = `
        <div class="card">
          <div class="title">
            <slot name="title">Standard-Titel</slot>
          </div>
          <div class="content">
            <slot>Kein Inhalt vorhanden.</slot>
          </div>
        </div>
      `;
    }
  }
  customElements.define("simple-card", SimpleCard);
</script>

<!-- Verwendung der Komponente -->
<simple-card>
  <span slot="title">Meine Karte</span>
  <p>Das ist der Inhalt, der im
    Default-Slot landet.</p>
</simple-card>
Vorschau

Die Komponente definiert zwei Slots: Einen Named Slot title und einen Default Slot für den restlichen Inhalt. Von außen wird <span slot="title"> dem Named Slot zugewiesen, und der <p> landet im Default Slot, weil er kein slot-Attribut hat.

Attribute

Attribut Typ Beschreibung Beispiel
name String Definiert den Namen des Slots. Kindelemente der Komponente mit einem passenden slot-Attribut werden in diesen Slot eingefügt. Ohne name-Attribut ist es der Default Slot. name="header"

Beispiele

Einfache Komponente mit Default Slot

Ein Card-Wrapper, der beliebigen Inhalt umschließt. Der Default Slot nimmt alles auf, was zwischen die Tags der Komponente geschrieben wird.

Default Slot
<script>
  class CardWrapper extends HTMLElement {
    constructor() {
      super();
      this.attachShadow({ mode: "open" });
      this.shadowRoot.innerHTML = `
        <div style="
          background: white;
          border: 1px solid #e5e7eb;
          border-radius: 12px;
          padding: 20px;
          box-shadow: 0 2px 8px rgba(0,0,0,0.08);
        ">
          <slot>Hier könnte dein Inhalt stehen.</slot>
        </div>
      `;
    }
  }
  customElements.define("card-wrapper", CardWrapper);
</script>

<card-wrapper>
  <h3>Willkommen!</h3>
  <p>Das ist ein einfacher Card-Wrapper.
    Der gesamte Inhalt wird über den
    Default Slot eingefügt.</p>
</card-wrapper>
Vorschau

Named Slots für mehrere Bereiche

Eine Komponente mit header, content und footer: drei klar getrennte Bereiche, die von außen befüllt werden. Jeder Bereich hat seinen eigenen Named Slot.

Named Slots
<script>
  class PageLayout extends HTMLElement {
    constructor() {
      super();
      this.attachShadow({ mode: "open" });
      this.shadowRoot.innerHTML = `
        <div class="layout">
          <header>
            <slot name="header">Header-Bereich</slot>
          </header>
          <main>
            <slot name="content">Hauptinhalt</slot>
          </main>
          <footer>
            <slot name="footer">Footer-Bereich</slot>
          </footer>
        </div>
      `;
    }
  }
  customElements.define("page-layout", PageLayout);
</script>

<page-layout>
  <span slot="header">Mein Dashboard</span>
  <div slot="content">
    <p>Hier stehen die wichtigsten Inhalte.</p>
    <p>Auch dieser Absatz gehört zum
      Content-Slot.</p>
  </div>
  <span slot="footer">© 2026 Meine Webseite</span>
</page-layout>
Vorschau

Fallback-Content

Wenn kein Inhalt für einen Slot zugewiesen wird, zeigt der Browser den Inhalt zwischen den <slot>-Tags als Fallback. Das ist nützlich für optionale Bereiche oder Standard-Werte.

Fallback-Content
<script>
  class UserProfile extends HTMLElement {
    constructor() {
      super();
      this.attachShadow({ mode: "open" });
      this.shadowRoot.innerHTML = `
        <div class="profile">
          <div class="avatar">
            <slot name="avatar">👤</slot>
          </div>
          <div class="name">
            <slot name="name">Unbekannter Nutzer</slot>
          </div>
          <div class="role">
            <slot name="role">Keine Rolle zugewiesen</slot>
          </div>
        </div>
      `;
    }
  }
  customElements.define("user-profile", UserProfile);
</script>

<!-- Mit Inhalt: Fallback wird ersetzt -->
<user-profile>
  <span slot="name">Mario</span>
  <span slot="role">Webentwickler</span>
</user-profile>

<!-- Ohne Inhalt: Fallback wird angezeigt -->
<user-profile></user-profile>
Vorschau

Die erste <user-profile> hat Name und Rolle gesetzt, aber keinen Avatar: dort greift der Fallback mit dem Standard-Emoji. Die zweite Komponente hat gar keinen Inhalt, daher werden alle drei Fallback-Texte angezeigt.

Barrierefreiheit

Die gute Nachricht: Slotted Content behält seine volle semantische Bedeutung. Wenn du ein <h2> oder ein <button> in einen Slot einfügst, bleibt es ein <h2> oder <button>, auch im Shadow DOM. Der Browser erstellt einen sogenannten Flattened Tree, den Screenreader und andere Hilfstechnologien lesen. In diesem Baum sind die projizierten Inhalte an ihrer visuellen Position, behalten aber ihre ursprüngliche Semantik.

  • Semantik bleibt erhalten: Slotted Elemente behalten ihre ARIA-Rollen, Labels und andere Accessibility-Attribute
  • Screenreader sehen den Flattened Tree: Assistive Technologien navigieren nicht durch den Shadow DOM, sondern durch die zusammengeführte Ansicht
  • Fokus-Reihenfolge folgt dem DOM: Die Tab-Reihenfolge richtet sich nach der Position der Elemente im Light DOM (dem DOM außerhalb des Shadow DOM), nicht nach der visuellen Position im Shadow DOM
  • Fallback-Content ist accessible: Wenn der Fallback-Content angezeigt wird, ist er genauso für Screenreader zugänglich wie regulärer Inhalt

Achte darauf, dass die Struktur deiner Slots logisch sinnvoll ist. Wenn ein Screenreader durch den Flattened Tree navigiert, sollte die Reihenfolge der Inhalte auch ohne visuelle Darstellung verständlich sein.

Häufige Fehler

<slot> außerhalb des Shadow DOM verwenden: Das ist der häufigste Fehler. Ein <slot> direkt im normalen HTML hat keine Wirkung. Es funktioniert nur innerhalb eines Shadow DOM, das du mit attachShadow() erstellst.

<!-- Falsch: slot ohne Shadow DOM -->
<div>
  <slot name="content">Das funktioniert nicht.</slot>
</div>

<!-- Richtig: slot im Shadow DOM -->
<script>
  class MyComponent extends HTMLElement {
    constructor() {
      super();
      this.attachShadow({ mode: "open" });
      this.shadowRoot.innerHTML = `
        <slot name="content">Das funktioniert!</slot>
      `;
    }
  }
  customElements.define("my-component", MyComponent);
</script>

name- und slot-Attribut verwechseln: Das name-Attribut gehört auf das <slot>-Element im Shadow DOM. Das slot-Attribut gehört auf das Kindelement im Light DOM, das in den Slot eingefügt werden soll. Die beiden arbeiten zusammen, sitzen aber an unterschiedlichen Stellen.

<!-- Im Shadow DOM der Komponente: -->
<slot name="header"></slot>

<!-- Bei der Verwendung der Komponente: -->
<my-component>
  <h2 slot="header">Titel</h2>
</my-component>

CSS-Isolation im Shadow DOM vergessen: CSS innerhalb des Shadow DOM ist isoliert: Styles von außen wirken nicht auf Slot-Inhalte im Shadow DOM, und Shadow-DOM-Styles wirken nicht auf die geslotteten Elemente. Du kannst ::slotted() verwenden, um geslottete Elemente von innerhalb des Shadow DOM zu stylen, aber nur für direkte Kinder des Slots.

/* Innerhalb des Shadow DOM: */
/* Funktioniert: direkte Kinder stylen */
::slotted(p) { color: blue; }

/* Funktioniert NICHT: verschachtelte Elemente */
::slotted(p span) { color: red; }

Browser-Kompatibilität

Das slot-Element wird als Teil der Web Components Spezifikation von allen modernen Browsern vollständig unterstützt.

ClientUnterstützungHinweise
ChromeKomplettVolle Unterstützung seit Chrome 53.
FirefoxKomplettVolle Unterstützung seit Firefox 63.
SafariKomplettVolle Unterstützung seit Safari 10.
EdgeKomplett
OperaKomplett

Email-Kompatibilität

Web Components und das slot-Element funktionieren in keinem Email-Client. JavaScript, Shadow DOM und Custom Elements werden in E-Mails nicht unterstützt.

ClientUnterstützungHinweise
Apple MailKeineKein Support für Web Components oder Shadow DOM.
GmailKeineEntfernt Custom Elements, script-Tags und slot-Elemente komplett.
OutlookKeineKeine Unterstützung für JavaScript oder Web Components.
ThunderbirdKeineKein Support für Shadow DOM oder Custom Elements.
Yahoo MailKeineEntfernt alle Web-Component-bezogenen Elemente.

Verwandte Elemente

Bleib auf dem Laufenden

Erhalte neue Inhalte direkt in dein Postfach

Mit der Anmeldung akzeptierst du unsere Datenschutzerklärung. Du kannst dich jederzeit über den Link in den E-Mails wieder abmelden.

Was erwartet dich?

Neue Artikel & Videos

Wenn ich was Neues veröffentliche, erfährst du's hier zuerst.

Plattform & Kurs-Updates

Neue Kurse, Referenz-Updates und gelegentlich Sonderpreise zum Launch.

Einmal die Woche in deinem Postfach

Kurz, auf den Punkt, kein Spam.