: The Content Template element - HTML | MDN (original) (raw)
Baseline
Widely available *
The <template>
HTML element serves as a mechanism for holding HTML fragments, which can either be used later via JavaScript or generated immediately into shadow DOM.
Attributes
This element includes the global attributes.
Creates a shadow root for the parent element. It is a declarative version of the Element.attachShadow() method and accepts the same enumerated values.
Exposes the internal shadow root DOM for JavaScript (recommended for most use cases).
Hides the internal shadow root DOM from JavaScript.
**Note:**The HTML parser creates a ShadowRoot object in the DOM for the first <template>
in a node with this attribute set to an allowed value. If the attribute is not set, or not set to an allowed value — or if a ShadowRoot
has already been declaratively created in the same parent — then an HTMLTemplateElement is constructed. A HTMLTemplateElement cannot subsequently be changed into a shadow root after parsing, for example, by setting HTMLTemplateElement.shadowRootMode.
**Note:**You may find the non-standard shadowroot
attribute in older tutorials and examples that used to be supported in Chrome 90-110. This attribute has since been removed and replaced by the standard shadowrootmode
attribute.
Sets the value of the clonable property of a ShadowRoot created using this element to true
. If set, a clone of the shadow host (the parent element of this <template>
) created with Node.cloneNode() or Document.importNode() will include a shadow root in the copy.
Sets the value of the delegatesFocus property of a ShadowRoot created using this element to true
. If this is set and a non-focusable element in the shadow tree is selected, then focus is delegated to the first focusable element in the tree. The value defaults to false
.
shadowrootserializable Experimental
Sets the value of the serializable property of a ShadowRoot created using this element to true
. If set, the shadow root may be serialized by calling the Element.getHTML() or ShadowRoot.getHTML() methods with the options.serializableShadowRoots
parameter set true
. The value defaults to false
.
Usage notes
There are two main ways to use the <template>
element.
Template document fragment
By default, the element's content is not rendered. The corresponding HTMLTemplateElement interface includes a standard content property (without an equivalent content/markup attribute). This content
property is read-only and holds a DocumentFragment that contains the DOM subtree represented by the template. This fragment can be cloned via the cloneNode method and inserted into the DOM.
Be careful when using the content
property because the returned DocumentFragment
can exhibit unexpected behavior. For more details, see the Avoiding DocumentFragment pitfalls section below.
Declarative Shadow DOM
If the <template>
element contains the shadowrootmode attribute with a value of either open
or closed
, the HTML parser will immediately generate a shadow DOM. The element is replaced in the DOM by its content wrapped in a ShadowRoot, which is attached to the parent element. This is the declarative equivalent of calling Element.attachShadow() to attach a shadow root to an element.
If the element has any other value for shadowrootmode
, or does not have the shadowrootmode
attribute, the parser generates a HTMLTemplateElement. Similarly, if there are multiple declarative shadow roots, only the first one is replaced by a ShadowRoot — subsequent instances are parsed as HTMLTemplateElement objects.
Examples
Generating table rows
First we start with the HTML portion of the example.
<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>
First, we have a table into which we will later insert content using JavaScript code. Then comes the template, which describes the structure of an HTML fragment representing a single table row.
Now that the table has been created and the template defined, we use JavaScript to insert rows into the table, with each row being constructed using the template as its basis.
// 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 = template.content.cloneNode(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 = template.content.cloneNode(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.
}
The result is the original HTML table, with two new rows appended to it via JavaScript:
table {
background: #000;
}
table td {
background: #fff;
}
Implementing a declarative shadow DOM
In this example, a hidden support warning is included at the beginning of the markup. This warning is later set to be displayed via JavaScript if the browser doesn't support the shadowrootmode
attribute. Next, there are two elements, each containing nested