1. html
  2. /tags
  3. /template



HTML provides the <template> element as a mechanism to contain fragments of HTML that are not immediately rendered when the page loads. These fragments remain inactive within the template, with styles unapplied and scripts unexecuted. They can be activated and inserted into the main document at runtime through JavaScript, enabling dynamic content creation and manipulation.

The <template> element has a unique characteristic: its content remains inert until it is cloned and appended to the live DOM, which refers to the part of the document that's currently rendered and active. This inert nature means that elements inside the template won't have any side effects, such as loading images or running scripts until activated. Additionally, the <template> content can be reused multiple times, making it apt for creating repeated structures or components.

Examples and Usage

In the illustrative example below, we'll create a dynamic task list where users can add tasks, and each task structure is defined using a <template> element. We'll present the HTML and JavaScript code and then explain how it operates, demonstrating the essence and potential of <template>.

<!-- Define the template for a task -->
<template id="task-template">
    <span class="task-title">Task: </span>
    <span class="task-content">Content</span>

<!-- Task list -->
<ul id="task-list"></ul>

<!-- Input for task wrapped inside a form to handle submission -->
<form id="task-form">
  <input type="text" id="task-input" placeholder="Enter your task here...">
  <button type="submit">Add Task</button>

  // Accessing the template element
  const template = document.getElementById("task-template");
  // Accessing the task list element
  const taskList = document.getElementById("task-list");
  // Initializing task count
  let taskCount = taskList.children.length;

  // Function to add a task
  function addTask() {
    // Retrieving task input value
    const taskInput = document.getElementById("task-input").value;
    // Validation for empty input
    if (taskInput.trim() === '') return;

    // Cloning the template content
    const task = template.content.cloneNode(true);
    // Incrementing task count
    // Updating task title and content
    task.querySelector(".task-title").innerText = `Task ${taskCount}: `;
    task.querySelector(".task-content").innerText = taskInput;
    // Appending task to the list

    // Clearing the task input
    document.getElementById("task-input").value = '';

  // Event listener for the form submission (clicking button or pressing Enter)
  document.getElementById("task-form").addEventListener("submit", function(event) {
    // Preventing default form submission
    // Calling the addTask function

For the sake of demonstration and brevity, we've included both HTML and JavaScript in one document. However, in larger projects, it's common to use external files to improve maintainability and separation of concerns.

Here's a quick breakdown of the setup:

  • Defining the Task Structure: We define a <template> with the id "task-template" that contains an HTML structure for a task, with placeholders for the task title and content. The content inside the <template> remains inert and does not affect the main DOM until activated.

  • User Interaction: We provide an input field and a button for users to add their tasks. These elements are outside the <template> and are part of the main document.

  • Dynamic Content Creation: The JavaScript function addTask is tied to the "Add Task" button. When clicked, this function retrieves the content of the <template> element, clones it using template.content.cloneNode(true), fills in the task details, appends it to the list, and clears the input field.

  • Cloning and Activation: The method cloneNode(true) creates a deep copy of the template content and activates it for insertion into the main document, making it part of the live DOM.

You can test this example in online code editors like CodePen, JSFiddle, or any environment of your choice. When a user enters a task and either clicks the "Add Task" button or presses the Enter key, the task gets appended to the list. The HTML structure for each task is cloned from the template, maintaining a clean and reusable pattern.

In addition, <template> offers encapsulation and isolation when used with the Shadow DOM, contributing to the modular and maintainable design often seen in Web Components.

In some cases, considering browser compatibility may be essential, and using polyfills might be necessary for older browsers that do not support the <template> element.

Attribute Breakdown

In addition to supporting global attributes, there's an experimental attribute called shadowrootmode, which is available in Chromium-based browsers. It enables the HTML parser to detect and apply the <template> element as the shadow root of its parent. More details for this proposal can be found here.

Accessibility Aspects

The <template> element does not have a corresponding ARIA role or utilize aria-* attributes. In terms of accessibility, it represents nothing within the rendered view, as its content is not displayed until activated through scripting.

Associated Elements

  • <slot>

Additional Notes

  • The <template> does not render before being activated, meaning assets, JavaScript, and initial CSS cannot be preloaded. It only renders when it becomes part of the live DOM, allowing for dynamic content manipulation.

  • If a template is nested within another, activating the outer one does not automatically activate the inner ones. Each nested template must be manually activated, ensuring precise control over the content that is rendered.

  • In the past, various methods were used to create reusable templates, such as "Offscreen DOM" (using hidden attributes or display:none) and overloading <script> tags. While these techniques work, they have downsides like non-inert content, painful styling, naming collisions, and potential security issues.

  • <template> provides a standardized, efficient way to manage reusable content without the drawbacks of older methods. It's an encapsulated, render-ready container that doesn't interact with the live DOM until activated.

Browser Compatibility

For a detailed breakdown of specific browser nuances and older version support refer to the first link in the Useful Resources below.

BrowserChromeEdgeSafariFirefoxOperaInternet Explorer

Useful Resources

Can I use HTML element: template

The HTML Living Standard Specification: template