<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 Shadow DOM generiert werden können.
Attribute
Dieses Element umfasst die globalen Attribute.
shadowrootmode-
Erstellt einen Shadow Root für das Elternelement. Es handelt sich um eine deklarative Version der Methode
Element.attachShadow()und akzeptiert dieselben enumerierten Werte.open-
Gibt das interne Shadow Root DOM für JavaScript frei (empfohlen für die meisten Anwendungsfälle).
closed-
Verbirgt das interne Shadow Root DOM vor JavaScript.
Hinweis: Der HTML-Parser erstellt ein
ShadowRoot-Objekt im DOM für das erste<template>in einem Knoten, bei dem dieses Attribut auf einen erlaubten Wert gesetzt ist. Wenn das Attribut nicht gesetzt ist, oder nicht auf einen erlaubten Wert gesetzt ist — oder wenn im gleichen Elternelement bereits einShadowRootdeklarativ erstellt wurde — wird einHTMLTemplateElementkonstruiert. EinHTMLTemplateElementkann nach dem Parsen nicht in ein Shadow Root geändert werden, zum Beispiel durch das Setzen vonHTMLTemplateElement.shadowRootMode.Hinweis: Sie können das nicht standardmäßige
shadowroot-Attribut in älteren Tutorials und Beispielen finden, das in Chrome 90-110 unterstützt wurde. Dieses Attribut wurde mittlerweile entfernt und durch das standardisierteshadowrootmode-Attribut ersetzt. shadowrootclonable-
Legt den Wert der
clonable-Eigenschaft eines mit diesem Element erstelltenShadowRootauftruefest. Wenn gesetzt, wird ein Klon des Shadow-Hosts (das Elternelement dieses<template>), der mitNode.cloneNode()oderDocument.importNode()erstellt wurde, einen Shadow Root in der Kopie enthalten. shadowrootdelegatesfocus-
Legt den Wert der
delegatesFocus-Eigenschaft eines mit diesem Element erstelltenShadowRootauftruefest. Wenn das gesetzt ist und ein nicht fokusierbares Element im Shadow Tree ausgewählt wird, wird der Fokus auf das erste fokusierbare Element im Baum delegiert. Der Wert ist standardmäßigfalse. shadowrootserializable-
Legt den Wert der
serializable-Eigenschaft eines mit diesem Element erstelltenShadowRootauftruefest. Wenn gesetzt, kann der Shadow Root durch Aufruf der MethodenElement.getHTML()oderShadowRoot.getHTML()mit dem Parameteroptions.serializableShadowRootsauftrueserialisiert werden. Der Wert ist standardmäßigfalse.
Nutzungshinweise
Dieses Element hat keinen erlaubten Inhalt, da alles, was im HTML-Code darin verschachtelt ist, tatsächlich nicht zu den Kindern des <template>-Elements wird. Die Node.childNodes-Eigenschaft des <template>-Elements ist immer leer, und Sie können auf den verschachtelten Inhalt nur über die spezielle content-Eigenschaft zugreifen. Wenn Sie jedoch Methoden wie Node.appendChild() auf das <template>-Element aufrufen, würden Sie Kinder in das <template>-Element selbst einfügen, was ein Verstoß gegen das Inhaltsmodell ist und das durch die content-Eigenschaft zurückgegebene DocumentFragment nicht tatsächlich aktualisiert.
Aufgrund der Art und Weise, wie das <template>-Element geparst wird, sind alle <html>, <head> und <body> öffnenden und schließenden Tags innerhalb des Templates Syntaxfehler und werden vom Parser ignoriert, sodass <template><head><title>Test</title></head></template> das gleiche ist wie <template><title>Test</title></template>.
Es gibt zwei Hauptmethoden, das <template>-Element zu verwenden.
Template-Dokumentfragment
Standardmäßig wird der Inhalt des Elements nicht gerendert.
Das entsprechende HTMLTemplateElement-Interface enthält eine standardmäßige content-Eigenschaft (ohne ein entsprechendes Inhalt/Markup-Attribut). Diese content-Eigenschaft ist schreibgeschützt und enthält ein DocumentFragment, das den DOM-Unterbaum enthält, der durch das Template dargestellt wird.
Die Methoden Node.cloneNode() und Document.importNode() erstellen beide eine Kopie eines Knotens. Der Unterschied besteht darin, dass importNode() den Knoten im Kontext des Aufrufdokuments klont, während cloneNode() das Dokument des zu klonenden Knotens verwendet. Der Dokumentkontext bestimmt das CustomElementRegistry für die Konstruktion aller benutzerdefinierten Elemente. Aus diesem Grund verwenden Sie document.importNode(), um das content-Fragment zu klonen, damit benutzerdefinierte Elementnachkommen unter Verwendung der Definitionen im aktuellen Dokument konstruiert werden, anstatt in dem separaten Dokument, das den Template-Inhalt besitzt. Weitere Details finden Sie auf der Seite Beispiele zu Node.cloneNode().
Beachten Sie, dass der DocumentFragment-Container selbst keine Daten enthalten sollte. Weitere Details finden Sie im Beispiel Daten im DocumentFragment werden nicht geklont.
Deklaratives Shadow DOM
Wenn das <template>-Element das Attribut shadowrootmode mit einem Wert von entweder open oder closed enthält, generiert der HTML-Parser sofort ein Shadow DOM. Das Element wird im DOM durch seinen Inhalt ersetzt, der in einem ShadowRoot verpackt ist, der dem Elternelement zugeordnet ist.
Dies ist das deklarative Äquivalent des Aufrufs von Element.attachShadow(), um einem Element einen Shadow Root zuzuweisen.
Wenn das Element einen anderen Wert für shadowrootmode hat oder nicht das Attribut shadowrootmode besitzt, generiert der Parser ein HTMLTemplateElement.
Ebenso, wenn mehrere deklarative Shadow Roots vorhanden sind, wird nur das erste durch ein ShadowRoot ersetzt — nachfolgende Instanzen werden als HTMLTemplateElement-Objekte geparst.
Beispiele
>Generieren von Tabellenzeilen
Zuerst 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 kommt das Template, das die Struktur eines HTML-Fragmentes beschreibt, das eine einzelne Tabellenzeile darstellt.
Nachdem die Tabelle erstellt und das Template definiert wurde, verwenden wir JavaScript, um Zeilen in die Tabelle einzufügen, wobei jede Zeile konstruiert wird, indem das Template als Grundlage verwendet wird.
// 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, der zwei neue Zeilen über JavaScript hinzugefügt werden:
Implementieren eines deklarativen Shadow DOM
In diesem Beispiel ist zu Beginn des Markups eine versteckte Unterstützung-Warnung enthalten, die später über JavaScript angezeigt wird, wenn der Browser das shadowrootmode-Attribut nicht unterstützt. Danach 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 anstelle des <template>-Elements erzeugt wird, da das Attribut shadowrootmode vorhanden ist.
<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);
Deklaratives Shadow DOM mit delegiertem Fokus
Dieses Beispiel zeigt, wie shadowrootdelegatesfocus auf einen deklarativ erstellten Shadow Root angewendet wird und welchen Effekt dies auf den Fokus hat.
Der Code deklariert zunächst einen Shadow Root innerhalb eines <div>-Elements, indem das <template>-Element mit dem Attribut shadowrootmode verwendet wird.
Dies zeigt sowohl ein nicht fokusierbares <div> mit Text als auch ein fokussierbares <input>-Element an.
Es verwendet auch CSS, um Elemente mit :focus blau zu färben und das normale Styling des Host-Elements festzulegen.
<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, außer dass er das Attribut shadowrootdelegatesfocus setzt, das den Fokus auf das erste fokusierbare Element im Baum delegiert, wenn ein nicht fokusierbares 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>
Zuletzt verwenden wir das folgende CSS, um dem übergeordneten <div>-Element einen roten Rand zu verleihen, wenn es den Fokus hat.
div:focus {
border: 2px solid red;
}
Die Ergebnisse werden unten gezeigt.
Wenn das HTML zuerst gerendert wird, haben die Elemente kein Styling, wie im ersten Bild gezeigt.
Für den Shadow Root, bei dem shadowrootdelegatesfocus nicht gesetzt ist, 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 den Shadow Root mit gesetztem shadowrootdelegatesfocus, indem Sie auf den Text (der nicht fokusierbar ist) klicken, wird das <input>-Element ausgewählt, da dies das erste fokusierbare Element im Baum ist.
Dies fokussiert auch das übergeordnete Element, wie unten gezeigt.

Daten im DocumentFragment werden nicht geklont
Wenn ein DocumentFragment-Wert übergeben wird, bewegen die Methoden Node.appendChild und ähnliche Methoden nur die Kindknoten dieses Wertes in den Zielknoten. Daher ist es üblicherweise vorzuziehen, Ereignishandler 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 nur seine Kinder zu container hinzugefügt, wenn appendChild aufgerufen wird; die Ereignishandler von firstClone werden nicht kopiert. Im Gegensatz dazu wird, weil ein Ereignishandler zum ersten Kindknoten von secondClone hinzugefügt wird, der Ereignishandler kopiert, wenn appendChild aufgerufen wird, und das Klicken darauf funktioniert wie erwartet.
Technische Übersicht
| Inhaltskategorien | Metadaten-Inhalte, Fluss-Inhalte, Phrasierungs-Inhalte, Skript-unterstützende Elemente |
|---|---|
| Erlaubte Inhalte | Nichts (siehe Nutzungshinweise) |
| Tag-Auslassung | Keine, sowohl das Start- als auch das End-Tag sind obligatorisch. |
| Erlaubte Eltern |
Jedes Element, das
Metadaten-Inhalt,
Phrasierungs-Inhalt oder
Skript-unterstützende Elemente akzeptiert. Ebenfalls erlaubt als Kind eines <colgroup>
Elements, das kein
span-Attribut hat.
|
| Implizite ARIA-Rolle | Keine entsprechende Rolle |
| Erlaubte ARIA-Rollen | Keine role erlaubt |
| DOM-Schnittstelle | [`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-PseudoelementeShadowRoot-Schnittstelle- Verwendung von Templates und Slots
- CSS Scoping Modul
- Deklaratives Shadow DOM (mit html) in Verwendung von Shadow DOM
- Deklaratives Shadow DOM auf web.dev (2023)