<template>: Das Content Template-Element
Baseline
Widely available
*
This feature is well established and works across many devices and browser versions. It’s been available across browsers since November 2015.
* Some parts of this feature may have varying levels of support.
Das <template> HTML Element dient als Mechanismus zum Halten von HTML Fragmenten, die entweder später über JavaScript verwendet oder sofort in den Shadow DOM generiert werden können.
Attribute
Dieses Element enthält die globalen Attribute.
shadowrootmode-
Erstellt eine Shadow-Root für das übergeordnete Element. Es ist eine deklarative Version der Methode
Element.attachShadow()und akzeptiert die gleichen aufgezählten Werte.open-
Macht den internen Shadow DOM für JavaScript zugänglich (empfohlen für die meisten Anwendungsfälle).
closed-
Verbirgt den internen Shadow DOM vor JavaScript.
Hinweis: Der HTML-Parser erstellt ein
ShadowRootObjekt im DOM für das erste<template>in einem Knoten mit diesem Attribut auf einen erlaubten Wert gesetzt. Wenn das Attribut nicht gesetzt ist, auf einen nicht erlaubten Wert gesetzt ist — oder wenn einShadowRootbereits deklarativ im gleichen übergeordneten Element erstellt worden ist — dann wird einHTMLTemplateElementkonstruiert. EinHTMLTemplateElementkann nach dem Parsen nicht mehr in eine Shadow-Root umgewandelt werden, zum Beispiel durch Setzen vonHTMLTemplateElement.shadowRootMode.Hinweis: Sie können das nicht standardmäßige
shadowrootAttribut in älteren Tutorials und Beispielen finden, das in Chrome 90-110 unterstützt wurde. Dieses Attribut wurde inzwischen entfernt und durch das standardmäßigeshadowrootmodeAttribut ersetzt. shadowrootclonable-
Setzt den Wert der
clonableEigenschaft eines mit diesem Element erstelltenShadowRootauftrue. Wenn gesetzt, wird ein Klon des Shadow-Hosts (des übergeordneten Elements dieses<template>) erstellt mitNode.cloneNode()oderDocument.importNode()und umfasst eine Shadow-Root in der Kopie. shadowrootdelegatesfocus-
Setzt den Wert der
delegatesFocusEigenschaft eines mit diesem Element erstelltenShadowRootauftrue. Wenn dies gesetzt ist und ein nicht fokussierbares Element im Shadow-Baum ausgewählt wird, wird der Fokus an das erste fokussierbare Element im Baum delegiert. Der Wert ist standardmäßigfalse. shadowrootreferencetargetExperimentell-
Setzt den Wert der
referenceTargetEigenschaft eines mit diesem Element erstelltenShadowRoot. Der Wert sollte die ID eines Elements innerhalb des Shadow DOM sein. Wenn gesetzt, führen Verweise auf das Host-Element von außerhalb des Shadow DOM dazu, dass das referenzierte Ziel-Element das effektive Ziel des Verweises auf das Host-Element wird. shadowrootserializable-
Setzt den Wert der
serializableEigenschaft eines mit diesem Element erstelltenShadowRootauftrue. Ist diese Option gesetzt, kann die Shadow-Root serialisiert werden, indem die MethodenElement.getHTML()oderShadowRoot.getHTML()aufgerufen werden, wobei der Parameteroptions.serializableShadowRootsauftruegesetzt ist. Der Wert ist standardmäßigfalse.
Nutzungshinweise
Dieses Element hat keinen erlaubten Inhalt, da alles, was darin im HTML-Quellcode verschachtelt ist, tatsächlich nicht die Kinder des <template> Elements wird. Die Node.childNodes Eigenschaft des <template> Elements ist immer leer und Sie können diesen verschachtelten Inhalt nur über die spezielle content Eigenschaft zugreifen. Wenn Sie jedoch Node.appendChild() oder ähnliche Methoden auf das <template> Element aufrufen, würden Sie Kinder in das <template> Element selbst einfügen, was ein Verstoß gegen sein Inhaltsmodell darstellt und nicht tatsächlich das DocumentFragment, das von der content Eigenschaft zurückgegeben wird, aktualisiert.
Aufgrund der Weise, wie das <template> Element geparst wird, sind alle Öffnungs- und Schließtags <html>, <head>, und <body> innerhalb des Templates Syntaxfehler und werden vom Parser ignoriert, sodass <template><head><title>Test</title></head></template> dasselbe ist wie <template><title>Test</title></template>.
Es gibt zwei Hauptwege zur Nutzung des <template> Elements.
Template-Dokumentfragment
Standardmäßig wird der Inhalt des Elements nicht gerendert.
Das entsprechende HTMLTemplateElement Interface enthält eine standardmäßige content Eigenschaft (ohne entsprechendes Content-/Markup-Attribut). Diese content Eigenschaft ist schreibgeschützt und enthält ein DocumentFragment, das den vom Template dargestellten DOM-Teilbaum umfasst.
Die Methoden Node.cloneNode() und Document.importNode() erstellen beide eine Kopie eines Knotens. Der Unterschied liegt darin, dass importNode() den Knoten im Kontext des aufrufenden Dokuments klont, während cloneNode() das Dokument des zu klonenden Knotens verwendet. Der Dokumentkontext bestimmt das CustomElementRegistry für die Erstellung aller benutzerdefinierten Elemente. Aus diesem Grund wird document.importNode() verwendet, um das content Fragment zu klonen, sodass benutzerdefinierte Elementnachkommen mit den Definitionen des aktuellen Dokuments und nicht des separaten Dokuments, das den Template-Inhalt besitzt, erstellt werden. Siehe die Beispiele auf der Seite Node.cloneNode() für weitere Details.
Beachten Sie, dass der DocumentFragment Container selbst keine Daten angehängt haben sollte. Siehe das Beispiel Daten auf dem DocumentFragment werden nicht geklont für weitere Details.
Deklarativer Shadow DOM
Wenn das <template> Element das Attribut shadowrootmode mit einem Wert von entweder open oder closed enthält, generiert der HTML-Parser sofort einen Shadow DOM. Das Element wird im DOM durch seinen Inhalt ersetzt, der in einer ShadowRoot eingebettet ist und an das übergeordnete Element angehängt wird.
Dies ist das deklarative Äquivalent zum Aufruf von Element.attachShadow(), um eine Shadow-Root an ein Element anzuhängen.
Falls das Element einen anderen Wert für shadowrootmode hat oder das Attribut shadowrootmode nicht vorhanden ist, generiert der Parser ein HTMLTemplateElement.
Ähnlich, wenn es mehrere deklarative Shadow-Roots gibt, wird nur die erste durch eine ShadowRoot ersetzt — nachfolgende Instanzen werden als HTMLTemplateElement Objekte geparst.
Beispiele
>Generieren von Tabellenzeilen
Erstens beginnen wir mit dem HTML-Teil des Beispiels.
<table id="producttable">
<thead>
<tr>
<td>UPC_Code</td>
<td>Product_Name</td>
</tr>
</thead>
<tbody>
<!-- existing data could optionally be included here -->
</tbody>
</table>
<template id="productrow">
<tr>
<td class="record"></td>
<td></td>
</tr>
</template>
Zuerst haben wir eine Tabelle, in die wir später Inhalte mit JavaScript-Code einfügen werden. Dann folgt das Template, das die Struktur eines HTML-Fragments beschreibt, welches eine einzelne Tabellenzeile darstellt.
Jetzt, da die Tabelle erstellt und das Template definiert wurde, verwenden wir JavaScript, um Zeilen in die Tabelle einzufügen, wobei jede Zeile auf dem Template basiert.
// Test to see if the browser supports the HTML template element by checking
// for the presence of the template element's content attribute.
if ("content" in document.createElement("template")) {
// Instantiate the table with the existing HTML tbody
// and the row with the template
const tbody = document.querySelector("tbody");
const template = document.querySelector("#productrow");
// Clone the new row and insert it into the table
const clone = document.importNode(template.content, true);
let td = clone.querySelectorAll("td");
td[0].textContent = "1235646565";
td[1].textContent = "Stuff";
tbody.appendChild(clone);
// Clone the new row and insert it into the table
const clone2 = document.importNode(template.content, true);
td = clone2.querySelectorAll("td");
td[0].textContent = "0384928528";
td[1].textContent = "Acme Kidney Beans 2";
tbody.appendChild(clone2);
} else {
// Find another way to add the rows to the table because
// the HTML template element is not supported.
}
Das Ergebnis ist die ursprüngliche HTML-Tabelle, mit zwei neuen Zeilen, die über JavaScript hinzugefügt wurden:
Implementierung eines deklarativen Shadow DOM
In diesem Beispiel wird eine versteckte Unterstützungsmeldung zu Beginn der Markup eingefügt. Diese Warnung wird später über JavaScript angezeigt, wenn der Browser das shadowrootmode Attribut nicht unterstützt. Dann gibt es zwei <article> Elemente, die jeweils verschachtelte <style> Elemente mit unterschiedlichem Verhalten enthalten. Das erste <style> Element ist global für das gesamte Dokument. Das zweite ist auf den Shadow-Root beschränkt, der aufgrund des Vorhandenseins des shadowrootmode Attributs anstelle des <template> Elements generiert wird.
<p hidden>
⛔ Your browser doesn't support <code>shadowrootmode</code> attribute yet.
</p>
<article>
<style>
p {
padding: 8px;
background-color: wheat;
}
</style>
<p>I'm in the DOM.</p>
</article>
<article>
<template shadowrootmode="open">
<style>
p {
padding: 8px;
background-color: plum;
}
</style>
<p>I'm in the shadow DOM.</p>
</template>
</article>
const isShadowRootModeSupported = Object.hasOwn(
HTMLTemplateElement.prototype,
"shadowRootMode",
);
document
.querySelector("p[hidden]")
.toggleAttribute("hidden", isShadowRootModeSupported);
Deklarativer Shadow DOM mit delegiertem Fokus
Dieses Beispiel zeigt, wie shadowrootdelegatesfocus auf eine Shadow-Root angewendet wird, die deklarativ erstellt wird, und welche Auswirkungen dies auf den Fokus hat.
Der Code erklärt zunächst eine Shadow-Root innerhalb eines <div> Elements unter Verwendung des <template> Elements mit dem shadowrootmode Attribut.
Dies zeigt sowohl ein nicht fokussierbares <div>, das Text enthält, als auch ein fokussierbares <input> Element an.
Es wird auch CSS verwendet, um Elemente mit :focus in Blau zu gestalten und das normale Styling des Host-Elements zu setzen.
<div>
<template shadowrootmode="open">
<style>
:host {
display: block;
border: 1px dotted black;
padding: 10px;
margin: 10px;
}
:focus {
outline: 2px solid blue;
}
</style>
<div>Clickable Shadow DOM text</div>
<input type="text" placeholder="Input inside Shadow DOM" />
</template>
</div>
Der zweite Codeblock ist identisch, mit dem Unterschied, dass er das shadowrootdelegatesfocus Attribut setzt, das den Fokus an das erste fokussierbare Element im Baum delegiert, wenn ein nicht fokussierbares Element im Baum ausgewählt wird.
<div>
<template shadowrootmode="open" shadowrootdelegatesfocus>
<style>
:host {
display: block;
border: 1px dotted black;
padding: 10px;
margin: 10px;
}
:focus {
outline: 2px solid blue;
}
</style>
<div>Clickable Shadow DOM text</div>
<input type="text" placeholder="Input inside Shadow DOM" />
</template>
</div>
Zu guter Letzt verwenden wir das folgende CSS, um ein rotes Rahmen zum übergeordneten <div> Element hinzuzufügen, wenn es den Fokus hat.
div:focus {
border: 2px solid red;
}
Die Ergebnisse sind unten zu sehen.
Wenn das HTML zunächst gerendert wird, haben die Elemente keine Formatierung, wie im ersten Bild zu sehen.
Für die Shadow-Root, die shadowrootdelegatesfocus nicht gesetzt hat, können Sie überall außer auf das <input> klicken und der Fokus ändert sich nicht (wenn Sie das <input> Element auswählen, sieht es aus wie das zweite Bild).

Für die Shadow-Root mit shadowrootdelegatesfocus eingestellt, führt das Klicken auf den Text (der nicht fokussierbar ist) dazu, dass das <input> Element ausgewählt wird, da dies das erste fokussierbare Element im Baum ist.
Dies fokussiert auch das übergeordnete Element, wie unten gezeigt.

Daten auf dem DocumentFragment werden nicht geklont
Wenn ein DocumentFragment Wert übergeben wird, verschieben Node.appendChild und ähnliche Methoden nur die Kindknoten dieses Wertes in den Zielknoten. Daher ist es in der Regel vorzuziehen, Event-Handler an die Kinder eines DocumentFragment anzuhängen, anstatt an das DocumentFragment selbst.
Betrachten Sie das folgende HTML und JavaScript:
HTML
<div id="container"></div>
<template id="template">
<div>Click me</div>
</template>
JavaScript
const container = document.getElementById("container");
const template = document.getElementById("template");
function clickHandler(event) {
event.target.append(" — Clicked this div");
}
const firstClone = document.importNode(template.content, true);
firstClone.addEventListener("click", clickHandler);
container.appendChild(firstClone);
const secondClone = document.importNode(template.content, true);
secondClone.children[0].addEventListener("click", clickHandler);
container.appendChild(secondClone);
Ergebnis
Da firstClone ein DocumentFragment ist, werden beim Aufrufen von appendChild nur dessen Kinder zu container hinzugefügt; die Event-Handler von firstClone werden nicht kopiert. Im Gegensatz dazu, da ein Event-Handler zum ersten Kindknoten von secondClone hinzugefügt wird, wird der Event-Handler beim Aufrufen von appendChild kopiert, und das Klicken darauf funktioniert, wie man es erwarten würde.
Technische Zusammenfassung
| Inhaltskategorien | Metadaten-Inhalt, Flussinhalt, Phraseninhalt, Skripte unterstützendes Element |
|---|---|
| Erlaubter Inhalt | Nichts (siehe Nutzungshinweise) |
| Tag-Auslassung | Keine, sowohl das Anfangs- als auch das End-Tag sind erforderlich. |
| Erlaubte Eltern |
Jedes Element, das
Metadaten-Inhalt,
Phraseninhalt oder
skriptunterstützende Elemente akzeptiert. Auch erlaubt als Kind eines <colgroup>
Elements, das kein
span Attribut hat.
|
| Implizite ARIA-Rolle | Keine entsprechende Rolle |
| Erlaubte ARIA-Rollen | Keine role erlaubt |
| DOM-Interface | [`HTMLTemplateElement`](/de/docs/Web/API/HTMLTemplateElement) |
Spezifikationen
| Specification |
|---|
| HTML> # the-template-element> |
Browser-Kompatibilität
Siehe auch
partundexportpartsHTML Attribute<slot>HTML Element:has-slotted,:host,:host()und:host-context()CSS Pseudoklassen::partund::slottedCSS PseudoelementeShadowRootInterface- Verwendung von Templates und Slots
- CSS-Bereichsanpassung Modul
- Deklarativer Shadow DOM (mit HTML) in Verwendung von Shadow DOM
- Deklarativer Shadow DOM auf web.dev (2023)