<template> / <slot>
| Since: | HTML Living Standard(2019〜) |
|---|
The template element defines a reusable HTML blueprint that is not rendered by the browser. The slot element is used in Web Components to define insertion points where external content can be injected inside a custom element. Web Components is a mechanism for creating reusable custom HTML elements. Shadow DOM isolates the internal HTML and CSS of a component from the outside.
Syntax
<!-- template: an HTML blueprint that is not rendered -->
<template id="card-template">
<div class="card">
<h2 class="card-title"></h2>
<p class="card-body"></p>
</div>
</template>
<!-- slot: insertion point for Web Components (used inside Shadow DOM) -->
<template id="my-card-template">
<style>
.card { border: 1px solid #ccc; padding: 16px; }
</style>
<div class="card">
<!-- unnamed slot (default slot) -->
<slot></slot>
<!-- named slot -->
<slot name="footer"></slot>
</div>
</template>
Attributes / Properties
| Attribute / Property | Description |
|---|---|
| template#content | A property that provides access to the contents of a template element. Returns the content as a DocumentFragment. |
| cloneNode(true) | A method that duplicates the template's content. Passing true performs a deep copy, including all child elements. |
| slot (attribute) | An attribute placed on a child element of a custom element. Specifies by name which slot the element should be inserted into. |
| slot name | The name assigned to a slot element inside a Shadow DOM. The matching child element of the custom element is inserted into this slot. |
Sample Code
sample_template_slot.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<style>
.card {
border: 1px solid #ddd;
border-radius: 8px;
padding: 16px;
margin: 8px;
max-width: 300px;
}
.card-title { font-weight: bold; font-size: 1.1em; margin: 0 0 8px; }
.card-body { color: #555; margin: 0; }
</style>
</head>
<body>
<!-- template element: not rendered by the browser -->
<template id="card-template">
<div class="card">
<p class="card-title"></p>
<p class="card-body"></p>
</div>
</template>
<div id="container"></div>
<script>
// Card data
var cards = [
{ title: 'HTML', body: 'The language for structuring web pages.' },
{ title: 'CSS', body: 'Handles the visual design of web pages.' },
{ title: 'JavaScript', body: 'Adds interactivity to web pages.' },
];
var template = document.getElementById('card-template');
var container = document.getElementById('container');
for (var i = 0; i < cards.length; i++) {
// Clone the template and fill in the data
var clone = template.content.cloneNode(true);
clone.querySelector('.card-title').textContent = cards[i].title;
clone.querySelector('.card-body').textContent = cards[i].body;
container.appendChild(clone);
}
</script>
</body>
</html>
Result
When the page loads, JavaScript clones the template three times and renders three cards — HTML, CSS, and JavaScript — stacked vertically. The template element itself is present in the HTML source but never appears on screen.
Overview
The template element is an HTML blueprint that is not rendered, styled, or scripted when the page loads. It only becomes visible after JavaScript clones it with cloneNode and appends it to the DOM. This approach is safer and more efficient than generating HTML from strings with innerHTML when you need to create the same structure repeatedly (such as lists, cards, or table rows). Passing user-supplied strings to innerHTML risks XSS, but setting values via cloneNode + textContent with a template element is XSS-safe.
The slot element is part of the Web Components specification (custom elements + Shadow DOM). It defines a "hole" into which users of a custom element can inject content from outside. An unnamed slot (the default slot) accepts all child elements of the custom element, while a named slot — identified by a name attribute — accepts only the specific child elements that carry a matching slot="name" attribute.
Web Components is a browser-native specification for building self-contained, encapsulated UI components with HTML and JavaScript — no framework required. While the Shadow DOM specification can be complex, a good starting point is the simpler use of the template element for reusable HTML blueprints. See also script / noscript for related elements.
Browser Compatibility
26 and later ○
25 and earlier ×
22 and later ○
21 and earlier ×
7 and earlier ×
14 and earlier ×
7 and earlier ×
Android Browser
4.4 and later ○
4 and earlier ×* Version data based on MDN.
Practical Use of template
<template> is especially useful when you need to dynamically generate the same HTML structure multiple times with JavaScript.
<!-- Define a card template -->
<template id="card-template">
<div class="card">
<img class="card-img" src="" alt="">
<div class="card-body">
<h3 class="card-title"></h3>
<p class="card-text"></p>
</div>
</div>
</template>
<!-- Container where cards will be displayed -->
<div id="card-container"></div>
<script>
var items = [
{ img: "cat.jpg", alt: "Photo of a cat", title: "Cat Cafe Visit", text: "Spent time with adorable cats." },
{ img: "dog.jpg", alt: "Photo of a dog", title: "Dog Park Trip", text: "Played with energetic dogs." }
];
var tmpl = document.getElementById('card-template');
var container = document.getElementById('card-container');
items.forEach(function(item) {
// Clone the template content (deep clone via importNode)
var clone = document.importNode(tmpl.content, true);
clone.querySelector('.card-img').src = item.img;
clone.querySelector('.card-img').alt = item.alt;
clone.querySelector('.card-title').textContent = item.title;
clone.querySelector('.card-text').textContent = item.text;
container.appendChild(clone);
});
</script>
Compared to generating HTML by string concatenation with innerHTML, using <template> reduces the risk of XSS and makes the structure clearer. Web Components (Custom Elements) also use <template> and <slot> together.
If you find any errors or copyright issues, please contact us.