<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 ein Shadow DOM generiert werden können.
Attribute
Dieses Element umfasst die globalen Attribute.
shadowrootmode-
Erstellt ein Shadow Root für das Elternelement. Es ist eine deklarative Version der Methode
Element.attachShadow()und akzeptiert die gleichen enumerierten Werte.open-
Macht das interne Shadow Root DOM für JavaScript sichtbar (empfohlen für die meisten Anwendungsfälle).
closed-
Verbirgt das interne Shadow Root DOM vor JavaScript.
Hinweis: Der HTML-Parser erstellt ein
ShadowRootObjekt 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 oder nicht auf einen erlaubten Wert gesetzt ist — oder wenn einShadowRootbereits deklarativ im gleichen Elternteil erstellt wurde — dann wird einHTMLTemplateElementkonstruiert. EinHTMLTemplateElementkann nach dem Parsen nicht nachträglich in ein Shadow Root geändert werden, zum Beispiel durch Setzen vonHTMLTemplateElement.shadowRootMode.Hinweis: Sie finden möglicherweise das nicht standardisierte
shadowrootAttribut in älteren Tutorials und Beispielen, das früher in Chrome 90-110 unterstützt wurde. Dieses Attribut wurde inzwischen entfernt und durch das standardisierteshadowrootmodeAttribut ersetzt. shadowrootclonable-
Setzt den Wert der
clonableEigenschaft einesShadowRoot, der mit diesem Element erstellt wurde, auftrue. Wenn gesetzt, wird ein Klon des Shadow Hosts (dem Elternelement dieses<template>) erstellt, indemNode.cloneNode()oderDocument.importNode()verwendet wird, der ein Shadow Root in der Kopie enthalten wird. shadowrootdelegatesfocus-
Setzt den Wert der
delegatesFocusEigenschaft einesShadowRoot, der mit diesem Element erstellt wurde, auftrue. 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. shadowrootserializable-
Setzt den Wert der
serializableEigenschaft einesShadowRoot, der mit diesem Element erstellt wurde, auftrue. Wenn gesetzt, kann das Shadow Root serialisiert werden, indem die MethodenElement.getHTML()oderShadowRoot.getHTML()mit demoptions.serializableShadowRootsParameter auftrueaufgerufen werden. Der Wert ist standardmäßigfalse.
Nutzungshinweise
Dieses Element hat keinen erlaubten Inhalt, da alles, was im HTML-Quelltext darin geschachtelt ist, nicht wirklich zu den Kindern des <template> Elements wird. Die Node.childNodes Eigenschaft des <template> Elements ist immer leer, und Sie können auf den geschachtelten Inhalt nur über die spezielle content Eigenschaft zugreifen. Wenn Sie jedoch Node.appendChild() oder ähnliche Methoden auf das <template> Element anwenden, dann würden Sie Kinder in das <template> Element selbst einfügen, was gegen sein Inhaltsmodell verstößt 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> öffnende und schließende Tags 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, das <template> Element zu nutzen.
Template-Dokumentfragment
Standardmäßig wird der Inhalt des Elements nicht gerendert.
Das entsprechende HTMLTemplateElement Interface beinhaltet eine standardmäßige content Eigenschaft (ohne äquivalentes Content/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 aufrufenden Dokuments klont, während cloneNode() das Dokument des geklonten Knotens verwendet. Der Dokumentkontext bestimmt das CustomElementRegistry zur Konstruktion von benutzerdefinierten Elementen. Aus diesem Grund verwenden Sie document.importNode(), um das content Fragment zu klonen, damit benutzerdefinierte Elementnachkommen mit den Definitionen im aktuellen Dokument konstruiert werden, anstatt das separate Dokument zu verwenden, das den Template-Inhalt besitzt. Sehen Sie sich die Beispiele auf der Seite Node.cloneNode() für weitere Details an.
Beachten Sie, dass der DocumentFragment Container selbst keine Daten enthalten sollte. Siehe das Beispiel Daten auf dem DocumentFragment werden nicht geklont für weitere Details.
Deklaratives Shadow DOM
Wenn das <template> Element das Attribut shadowrootmode mit einem Wert von entweder open oder closed enthält, wird vom HTML-Parser sofort ein Shadow DOM generiert. Das Element wird im DOM durch seinen Inhalt ersetzt, der in ein ShadowRoot gewickelt ist, das dem Elternelement angehängt wird.
Dies ist das deklarative Äquivalent zum Aufruf von Element.attachShadow(), um ein Shadow Root an ein Element anzuhängen.
Wenn das Element einen anderen Wert für shadowrootmode hat oder nicht das Attribut shadowrootmode besitzt, generiert der Parser ein HTMLTemplateElement.
Ebenso wird bei mehreren deklarativen Shadow Roots nur das erste durch ein ShadowRoot ersetzt — nachfolgende Instanzen werden als HTMLTemplateElement Objekte geparst.
Beispiele
>Tabellenzeilen generieren
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 folgt das Template, das die Struktur eines HTML-Fragments 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 unter Verwendung des Templates als Basis konstruiert 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 mit zwei neuen Zeilen, die über JavaScript hinzugefügt wurden:
Implementierung eines deklarativen Shadow DOM
In diesem Beispiel wird zu Beginn des Markups eine versteckte Support-Warnung eingefügt. Diese Warnung wird später über JavaScript angezeigt, wenn der Browser das shadowrootmode Attribut nicht unterstützt. Als nächstes gibt es zwei <article> Elemente, die geschachtelte <style> Elemente mit unterschiedlichen Verhaltensweisen enthalten. Das erste <style> Element ist global für das gesamte Dokument. Das zweite ist auf das Shadow Root beschränkt, das anstelle des <template> Elements aufgrund des Vorhandenseins des shadowrootmode Attributs 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);
Deklaratives Shadow DOM mit delegiertem Fokus
Dieses Beispiel veranschaulicht, wie shadowrootdelegatesfocus auf ein deklarativ erstelltes Shadow Root angewendet wird und welchen Effekt dies auf den Fokus hat.
Der Code deklariert zuerst ein Shadow Root in einem <div> Element, indem das <template> Element mit dem shadowrootmode Attribut verwendet wird.
Dies zeigt sowohl ein nicht fokussierbares <div> an, das Text enthält, als auch ein fokussierbares <input> Element.
Mit CSS werden zudem Elemente mit :focus blau dargestellt, und das normale Styling des Host-Elements festgelegt.
<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 das Attribut shadowrootdelegatesfocus gesetzt wird, wodurch der Fokus an das erste fokussierbare Element im Baum delegiert wird, 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>
Abschließend verwenden wir folgendes CSS, um dem Elternelement <div> bei Fokus einen roten Rahmen zu geben.
div:focus {
border: 2px solid red;
}
Die Ergebnisse sind unten zu sehen.
Wenn das HTML zuerst gerendert wird, haben die Elemente kein Styling, wie im ersten Bild gezeigt.
Für das Shadow Root, das shadowrootdelegatesfocus nicht gesetzt hat, können Sie überall außer dem <input> klicken und der Fokus ändert sich nicht (wenn Sie das <input> Element auswählen, sieht es aus wie im zweiten Bild).

Für das Shadow Root mit gesetztem shadowrootdelegatesfocus bewirkt ein Klick auf den Text (der nicht fokussierbar ist), dass das <input> Element ausgewählt wird, da dies das erste fokussierbare Element im Baum ist.
Dies fokussiert auch das Elternelement, 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 Werts in den Zielknoten. Daher ist es in der Regel vorzuziehen, Ereignishandler an den Kindern eines DocumentFragment anzubringen statt am DocumentFragment selbst.
Betrachten Sie folgendes 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 Aufruf von appendChild nur seine Kinder zum container hinzugefügt; die Ereignishandler von firstClone werden nicht kopiert. Im Gegensatz dazu wird, weil ein Ereignishandler dem ersten Kindknoten von secondClone hinzugefügt wird, dieser beim Aufruf von appendChild kopiert, und ein Klick darauf funktioniert wie erwartet.
Technische Zusammenfassung
| Inhaltskategorien | Metadaten-Inhalt, Fluss-Inhalt, Phrasen-Inhalt, Script-unterstützendes Element |
|---|---|
| Erlaubter Inhalt | Nichts (siehe Nutzungshinweise) |
| Tag-Auslassung | Keine, sowohl das öffnende als auch das schließende Tag sind erforderlich. |
| Erlaubte Eltern |
Jedes Element, das
Metadaten-Inhalt,
Phrasen-Inhalt, oder
Script-unterstützende Elemente akzeptiert. Auch erlaubt als Kind eines <colgroup>
Elements, das nicht ein
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-PseudoelementeShadowRootSchnittstelle- Verwendung von Templates und Slots
- CSS-Scopeing Modul
- Deklaratives Shadow DOM (mit HTML) in Using Shadow DOM
- Deklaratives Shadow DOM auf web.dev (2023)