Template Element

In this chapter, we cover a built-in template element, serving as a storage for HTML markup templates. Its contents are ignored by the browser. It only checks for syntax validity. However, it can be accessed and used in JavaScript for creating other elements.

Now, let’s see what is so unique about the <template>. First and foremost, any valid HTML can serve as its content. In the example below, a table row <tr> is placed there:

<template>
  <tr>
    <td>The Content</td>
  </tr>
</template>

But, note that if you attempt to put <tr> in a <div>, the browser will detect an invalid DOM structure and fix it, adding <table> around.

Also, you can put scripts and styles into <template> like this:

<template>
  <style>
    p { font-weight: bold; }
  </style>
  <script>
    alert("Welcome to W3Docs");
  </script>
</template>

So, the <template> content can be considered out of the document. Hence, styles will not be applied, scripts will not be executed. The content will become live only after inserting it into the document.

Inserting Template

The template content is reachable within its content property as a DocumentFragment (a specific DOM node type).

It can be dealt with like any other DOM node, without a single specific property (while inserting it the children are inserted instead).

Here is an example:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
  </head>
  <body>
    <template id="tmpId">
      <script>
        alert("Welcome to W3Docs");
      </script>
      <div class="message">Welcome to W3Docs!</div>
    </template>
    <script>
      let elem = document.createElement('div'); 
      // Clone the contents of the template to use it several times
      elem.append(tmpId.content.cloneNode(true)); 
      document.body.append(elem);
      // Now the script from <template>  is run
    </script>
  </body>
</html>

We can also try to rewrite an example from Shadow DOM chapter by applying <template> like this:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
  </head>
  <body>
    <template id="tmpl">
      <style> p { font-weight: bold; } </style>
      <p id="message"></p>
    </template>
    <div id="elem">Click me</div>
    <script>
      elem.onclick = function() {
        elem.attachShadow({mode: 'open'}); 
        elem.shadowRoot.append(tmpl.content.cloneNode(true)); // (*) 
        elem.shadowRoot.getElementById('message').innerHTML = "Welcome to W3Docs! Hello from the shadows";
      };
    </script>
  </body>
</html>

In the (*) line, while cloning and inserting tmpl.content as its DocumentFragment, the children (<style>, <p>) will be inserted instead. The shadow DOM will be formed by them:

<div id="elem">
  #shadow-root
  <style> h1 { font-weight: bold; } </style>
  <h1 id="message"></h1>
</div>

Summary

To be brief, the built-in <template> element represents a storage for HTML markup templates.

Any syntactically correct HTML can be <template>.

In case the <template> content doesn’t affect anything, it is considered “out of the document”. The template.content can be accessed from JavaScript, as well as be cloned for reusing in a new component.

The <template> element can’t feature any iteration mechanisms, data bindings, or variable substitutions but can perform that on top of it.




Do you find this helpful?

Related articles