mitmario.dev

<template>

Das <template>-Element definiert wiederverwendbare HTML-Vorlagen, die beim Laden der Seite nicht gerendert werden. Der Inhalt eines Templates ist komplett inert: Kein CSS wird angewendet, keine Scripts werden ausgeführt, keine Bilder werden geladen. Erst wenn du per JavaScript mit content.cloneNode(true) eine Kopie erstellst und diese ins DOM einfügst, wird der Inhalt sichtbar und aktiv. Das macht <template> zu einem wichtigen Baustein für Web Components und dynamische UIs.

Steckbrief <template>
Kategorie
Einbettung & Widgets
Art
Metadaten
Beispiele
4
Browser
5 von 5
E-Mail
0 von 5
Stand
06.02.2026

Grundlagen

Das <template>-Element ist ein besonderer Container, dessen Inhalt vom Browser zwar geparst, aber nicht gerendert wird. Das ist ein entscheidender Unterschied zu einem Element mit display: none, denn ein verstecktes <div> wird trotzdem vollständig verarbeitet: Bilder werden geladen, Scripts ausgeführt, CSS berechnet. Bei <template> passiert nichts davon.

  • Der Inhalt eines Templates wird vom HTML-Parser validiert, aber nicht ausgeführt: keine Script-Ausführung, kein Bild-Download, kein CSS-Rendering
  • Die Eigenschaft content gibt ein DocumentFragment zurück, ein leichtgewichtiges DOM-Objekt, das den Template-Inhalt enthält
  • Mit content.cloneNode(true) erstellst du eine tiefe Kopie des Template-Inhalts, die du ins DOM einfügen kannst
  • Du kannst ein Template beliebig oft klonen, jede Kopie ist unabhängig
  • Templates sind die Grundlage für Web Components: In Kombination mit customElements.define() und Shadow DOM lassen sich eigene HTML-Elemente mit gekapseltem Markup erstellen
  • Ein Template kann jedes gültige HTML enthalten: Elemente, Text, sogar <style>- und <script>-Tags (die erst nach dem Einfügen aktiv werden)
  • Templates haben keine visuellen Attribute, sie sind rein strukturelle Container

Syntax

index.html
Grundsyntax
<template id="gruss-template">
  <div class="gruss">Hallo Welt!</div>
</template>

<button id="add-btn">Element hinzufügen</button>
<div id="container"></div>

<script>
  const button = document.getElementById("add-btn");
  const template = document.getElementById("gruss-template");
  const container = document.getElementById("container");

  button.addEventListener("click", () => {
    // Tiefe Kopie des Template-Inhalts erstellen
    const clone = template.content.cloneNode(true);
    // Kopie ins DOM einfügen
    container.appendChild(clone);
  });
</script>

Der entscheidende Ablauf: template.content liefert ein DocumentFragment, cloneNode(true) erstellt eine tiefe Kopie davon, und appendChild() fügt die Kopie ins sichtbare DOM ein. Jeder Klick erzeugt eine neue, unabhängige Kopie.

Beispiele

4 Beispiele

Ein häufiger Anwendungsfall: Du hast eine Liste und willst per Klick neue Einträge hinzufügen. Das Template definiert die Struktur eines einzelnen Listenelements, und JavaScript klont es bei Bedarf.

index.html
Liste dynamisch erweitern
<template id="item-template">
  <li class="list-item">Neuer Eintrag</li>
</template>

<input id="item-input" type="text"
       placeholder="Neuen Eintrag eingeben..." />
<button id="add-item-btn">Hinzufügen</button>
<ul id="item-list"></ul>

<script>
  const input = document.getElementById("item-input");
  const button = document.getElementById("add-item-btn");
  const template = document.getElementById("item-template");
  const list = document.getElementById("item-list");

  button.addEventListener("click", () => {
    const text = input.value.trim();
    if (!text) return;

    const clone = template.content.cloneNode(true);
    clone.querySelector("li").textContent = text;
    list.appendChild(clone);

    input.value = "";
    input.focus();
  });
</script>

Das Template liefert die Grundstruktur, und per textContent wird der Text vor dem Einfügen angepasst. So trennst du Markup-Struktur sauber von den dynamischen Daten.

Barrierefreiheit

Der Inhalt eines <template>-Elements ist unsichtbar und unerreichbar für Screenreader, und das ist gewollt. Ein Template ist eine Vorlage, kein sichtbarer Inhalt. Erst nachdem du einen Klon per JavaScript ins DOM eingefügt hast, wird der Inhalt für assistive Technologien zugänglich.

Das bedeutet in der Praxis:

  • Der Template-Inhalt selbst braucht keine ARIA-Attribute, er ist nicht Teil des Accessibility Trees
  • Achte darauf, dass die geklonten Elemente barrierefrei sind: Semantische HTML-Elemente, aussagekräftige Texte und korrekte Überschriften-Hierarchien
  • Wenn du Inhalte dynamisch per Template einfügst, können Screenreader-Nutzer das nicht automatisch mitbekommen. Verwende bei Bedarf aria-live="polite" auf dem Container, in den du die Klone einfügst. Damit kündigt der Screenreader neue Inhalte an
  • Bei Web Components mit Shadow DOM: <slot>-Elemente geben den eingesetzten Inhalt korrekt an den Accessibility Tree weiter

Häufige Fehler

5 Fehler
01 Template per CSS stylen wollen
Ein <template>-Element wird nicht gerendert, egal welche CSS-Regeln du darauf anwendest. Es hat kein visuelles Box-Modell, keine Dimensionen, keine Position. Wenn du den Template-Inhalt vor dem Klonen sehen willst, verwendest du das falsche Element. Templates sind unsichtbare Vorlagen, keine versteckten Container.
02 innerHTML statt content.cloneNode verwenden
Ein häufiger Anfängerfehler ist container.innerHTML = template.innerHTML. Das funktioniert zwar oberflächlich, aber du verlierst Event-Listener, umgehst den sicheren DocumentFragment-Mechanismus und riskierst XSS-Probleme. Verwende immer template.content.cloneNode(true), das ist der vorgesehene und sichere Weg.
03 Scripts im Template erwarten, dass sie automatisch laufen
JavaScript in einem <script>-Tag innerhalb eines Templates wird nicht ausgeführt, weder beim Laden der Seite noch beim Klonen und Einfügen ins DOM. Wenn du Script-Logik brauchst, schreibe sie außerhalb des Templates oder füge das Script-Element nach dem Klonen manuell dem DOM hinzu.
04 Template nur einmal verwenden statt klonen
Wenn du document.getElementById("template").content direkt (ohne cloneNode) an appendChild() übergibst, wird der Inhalt aus dem Template verschoben statt kopiert. Danach ist das Template leer, und du kannst es nicht erneut verwenden. Verwende immer cloneNode(true), um eine Kopie zu erstellen.
05 Template-Inhalt per JavaScript durchsuchen, bevor er im DOM ist
Nach dem Klonen mit cloneNode(true) erhältst du ein DocumentFragment. Du kannst auf diesem Fragment querySelector() verwenden, aber sobald du es per appendChild() einfügst, wird das Fragment geleert. Wenn du Referenzen auf eingefügte Elemente brauchst, hole sie dir nach dem Einfügen aus dem DOM oder vor dem Einfügen aus dem Fragment.

Browser-Kompatibilität

5 von 5

Das template-Element wird von allen modernen Browsern vollständig unterstützt. Es gehört zum HTML5-Standard und ist seit vielen Jahren stabil implementiert.

  • Chrome

    Komplett

    Vollständige Unterstützung seit Chrome 26.

  • Firefox

    Komplett

    Vollständige Unterstützung seit Firefox 22.

  • Safari

    Komplett

    Vollständige Unterstützung seit Safari 8.

  • Edge

    Komplett

  • Opera

    Komplett

Email-Kompatibilität

0 von 5

Das template-Element wird von keinem E-Mail-Client unterstützt. E-Mail-Clients erlauben kein JavaScript, und ohne JavaScript kann der Template-Inhalt nicht geklont und eingefügt werden. Der Inhalt bleibt unsichtbar.

  • Apple Mail

    Keine

    Template-Inhalt wird nicht gerendert. Kein JavaScript verfügbar.

  • Gmail

    Keine

    Entfernt das template-Element und seinen Inhalt komplett.

  • Outlook

    Keine

    Keine Unterstützung. Template-Inhalt bleibt unsichtbar.

  • Thunderbird

    Keine

    Template-Element wird ignoriert, Inhalt nicht angezeigt.

  • Yahoo Mail

    Keine

    Entfernt template-Elemente und JavaScript.

Newsletter

einmal die Woche, kostenlos

Neue Artikel und Videos, was sich auf der Lernplattform tut, und ab und zu ein Sonderpreis zum Kursstart. Kurz genug, dass du es auch liest.

Zuletzt verschickt · KW 40

Einmal alles neu, und die Lernplattform ist da

Danach kommt eine Mail mit Bestätigungslink, erst dann bist du eingetragen. Abmelden geht unten in jeder Ausgabe. Mehr dazu in der Datenschutzerklärung.