<template>
Defines a container for content that should be hidden when the page loads
✨ HTML5Definition and Usage
The <template> tag is used to hold HTML content
that is not to be rendered immediately when a page loads.
The content inside <template> can be rendered
later with JavaScript. It is inert until activated, meaning:
- Content is not displayed to the user
- Scripts do not run
- Images are not loaded
- Media does not play
- Form elements are not submitted
<template> tag to
create reusable content fragments that can be cloned and inserted
into the document using JavaScript.
<template> tag is
new in HTML5 and is a key component for building web components.
Browser support and standards
Browser rendering and modern HTML conformance are different questions. Check the current element reference for the browsers and features your project needs; the older source version table is not a current compatibility guarantee.
Read the MDN element referenceAttributes
The <template> tag supports the
Global Attributes in HTML.
The <template> tag also supports the
Event Attributes in HTML.
Examples
Basic Template Cloning
Create a simple template and clone it with JavaScript:
Example
<template id="myTemplate">
<div class="message">
<h3>Hello from Template!</h3>
<p>This content was hidden until cloned.</p>
</div>
</template>
<div id="container"></div>
<script>
// Get the template
const template = document.getElementById('myTemplate');
// Clone the template content
const clone = template.content.cloneNode(true);
// Insert the clone into the document
document.getElementById('container').appendChild(clone);
</script>
Template for List Items
Use a template to dynamically generate list items:
Example
<template id="listItemTemplate">
<li class="list-item">
<span class="item-name"></span>
<button class="delete-btn">Delete</button>
</li>
</template>
<ul id="itemList"></ul>
<script>
const items = ['Apple', 'Banana', 'Orange'];
const template = document.getElementById('listItemTemplate');
const list = document.getElementById('itemList');
items.forEach(item => {
const clone = template.content.cloneNode(true);
clone.querySelector('.item-name').textContent = item;
list.appendChild(clone);
});
</script>
Card Component Template
Create a reusable card component:
Example
<template id="cardTemplate">
<div class="card">
<img class="card-image" src="" alt="">
<div class="card-content">
<h3 class="card-title"></h3>
<p class="card-description"></p>
<button class="card-button">Learn More</button>
</div>
</div>
</template>
<div id="cardContainer"></div>
<script>
const cardData = {
image: 'product.jpg',
title: 'Product Name',
description: 'This is a great product.'
};
const template = document.getElementById('cardTemplate');
const clone = template.content.cloneNode(true);
clone.querySelector('.card-image').src = cardData.image;
clone.querySelector('.card-title').textContent = cardData.title;
clone.querySelector('.card-description').textContent = cardData.description;
document.getElementById('cardContainer').appendChild(clone);
</script>
Table Row Template
Generate dynamic table rows from a template:
Example
<table>
<thead>
<tr>
<th>Name</th>
<th>Email</th>
<th>Role</th>
</tr>
</thead>
<tbody id="userTable"></tbody>
</table>
<template id="userRowTemplate">
<tr>
<td class="user-name"></td>
<td class="user-email"></td>
<td class="user-role"></td>
</tr>
</template>
<script>
const users = [
{ name: 'John Doe', email: 'john@example.com', role: 'Admin' },
{ name: 'Jane Smith', email: 'jane@example.com', role: 'User' }
];
const template = document.getElementById('userRowTemplate');
const tbody = document.getElementById('userTable');
users.forEach(user => {
const clone = template.content.cloneNode(true);
clone.querySelector('.user-name').textContent = user.name;
clone.querySelector('.user-email').textContent = user.email;
clone.querySelector('.user-role').textContent = user.role;
tbody.appendChild(clone);
});
</script>
Reusable Widget Template
Create a notification widget template:
Example
<template id="notificationTemplate">
<div class="notification">
<span class="notification-icon"></span>
<div class="notification-content">
<h4 class="notification-title"></h4>
<p class="notification-message"></p>
</div>
<button class="notification-close">×</button>
</div>
</template>
<div id="notifications"></div>
<script>
function showNotification(type, title, message) {
const template = document.getElementById('notificationTemplate');
const clone = template.content.cloneNode(true);
const notification = clone.querySelector('.notification');
notification.classList.add('notification-' + type);
clone.querySelector('.notification-icon').textContent =
type === 'success' ? '✓' : type === 'error' ? '✗' : 'ℹ';
clone.querySelector('.notification-title').textContent = title;
clone.querySelector('.notification-message').textContent = message;
document.getElementById('notifications').appendChild(clone);
}
showNotification('success', 'Success!', 'Your changes have been saved.');
</script>
Template with Slot (Web Components)
Use templates with slots for flexible web components:
Example
Approved-page light CSS-variable defaults are supplied: --border-color, --bg-primary. The snippet includes CSS inside its HTML. The snippet includes JavaScript inside its HTML.
<template id="customCardTemplate">
<style>
.custom-card {
border: 1px solid var(--border-color);
padding: 20px;
border-radius: 8px;
background: var(--bg-primary);
}
</style>
<div class="custom-card">
<h3><slot name="title">Default Title</slot></h3>
<div><slot name="content">Default content</slot></div>
</div>
</template>
<script>
class CustomCard extends HTMLElement {
constructor() {
super();
const template = document.getElementById('customCardTemplate');
const shadowRoot = this.attachShadow({ mode: 'open' });
shadowRoot.appendChild(template.content.cloneNode(true));
}
}
customElements.define('custom-card', CustomCard);
</script>
<custom-card>
<span slot="title">My Custom Card</span>
<div slot="content">This is custom content!</div>
</custom-card>
Try it Yourself
Interactive Example
Click the button below to clone content from a template:
This content was created from a template!
How Template Works
Inert Content
Content inside <template> is completely inert
until activated:
- Not rendered: The content is not displayed on the page
- No side effects: Scripts don't execute, images don't load, media doesn't play
- Not in DOM: Template content is stored in a separate document fragment
- Reusable: Can be cloned multiple times without affecting the original
Cloning Process
Example
// 1. Get the template element
const template = document.getElementById('myTemplate');
// 2. Access the template content (DocumentFragment)
const templateContent = template.content;
// 3. Clone the content (deep clone with true)
const clone = templateContent.cloneNode(true);
// 4. Modify the clone if needed
clone.querySelector('.title').textContent = 'New Title';
// 5. Append to the document
document.body.appendChild(clone);
Template vs Hidden Content
| Feature | <template> | hidden attribute / display:none |
|---|---|---|
| In DOM | No (separate fragment) | Yes |
| Scripts Execute | No | Yes |
| Images Load | No | Yes |
| Can be Cloned | Yes (multiple times) | No (single instance) |
| Performance | Better (no rendering) | Worse (rendered but hidden) |
Web Components Usage
The <template> tag is a fundamental part of Web
Components, used alongside Custom Elements and Shadow DOM:
- Define reusable component structure
- Encapsulate styles within Shadow DOM
- Create custom HTML elements
-
Use with
<slot>for flexible content insertion
Best Practices
-
Use
<template>for content that will be repeated or dynamically created -
Always use
cloneNode(true)for deep cloning to include all child elements - Place templates near the top of your HTML for better organization
- Use descriptive IDs for templates to make them easy to reference
- Combine with web components for truly reusable, encapsulated components
- Remember that template content is not searchable by regular DOM queries
- Use templates to improve performance by avoiding hidden DOM elements
-
Consider using templates with
<slot>for flexible component design
Default CSS Settings
Most browsers will display the
<template> element with the following default
values:
Default CSS
Unavailable or blocked: markup context “Matching lesson markup is not supplied; this fragment uses a generic HTML scaffold.”. Provide inline styles and scripts, embedded images or the missing HTML context. External requests and browser dialogs stay blocked.
template {
display: none;
}
Related Tags
-
<slot>
Defines a slot in web components
-
<script>
Defines client-side JavaScript
-
<noscript>
Defines alternate content for no script
-
<object>
Defines embedded object
-
<iframe>
Defines an inline frame