template
Summary
Templates allow you to declare fragments of markup which are parsed as HTML, go unused at page load, but can be instantiated later on at runtime.
Overview Table
The content of a <template>
element is a hidden portion of the DOM and does not render on page load: scripts don’t run, text or images don’t display, audio doesn’t play, and so forth. Neither are the child nodes of the <template>
accessible with the JavaScript getElementbyId()
or querySelector()
methods.
Templates can be placed anywhere inside of the <head>
, <body>
, and <frameset>
elements; It can also be used as a child of a <table>
or a <select>
element.
Examples
Basic example
<table>
<tr>
<template id="cells-to-repeat">
<td>some content</td>
</template>
</tr>
</table>
To use a template, you need to activate it. Otherwise its content will not render. The simplest way to do this is by creating a deep copy of its .content
using cloneNode()
. The .content
property is read-only and references a DocumentFragment
containing the guts of a template.
var t = document.querySelector('#mytemplate');
t.content.querySelector('img').src = 'logo.png'; // Populate the src at runtime.
document.body.appendChild(t.content.cloneNode(true));
Shadow DOM example
But the more interesting use of the <template>
tag is in concert with the Shadow DOM and the <content>
tag. Use the Shadow DOM to achieve an encapsulation of the presentation (style) of the element and the <content>
tag to provide separation of content from the element. The element (shadow host) is implemented with a <template>
that encapsulates the styles, thereby providing a boiler plate, and a <content>
tag, thereby providing for the reuse of the template for different content.
<template id="nameTagTemplate">
<style>
…
</style>
<div class="outer">
<div class="boilerplate">
Hi! My name is
</div>
<div class="name">
<content></content>
</div>
</div>
</template>
<div id="nameTag"></div>
Now all you have to do to stamp out the element is run your template through the ShadowRoot.
var shadow = document.querySelector('#nameTag').webkitCreateShadowRoot();
var template = document.querySelector('#nameTagTemplate');
document.querySelector('#nameTag').textContent = 'Shellie';
shadow.appendChild(template.content);
template.remove();
Usage
The template contents are hidden implicitly since they are not part of the document. The template element itself must be hidden through the user agent style sheet, as in the following:
@namespace "http://www.w3.org/1999/xhtml";
template {
display : none;
}
Notes
- If you’re using modpagespeed, be careful of this bug. Templates that define inline
<style scoped>
, many be moved to thehead
with PageSpeed’s CSS rewriting rules. - There’s no way to “prerender” a template, meaning you cannot preload assets, process JS, download initial CSS, etc. That goes for both server and client. The only time a template renders is when it goes live.
- Be careful with nested templates. They don’t behave as you might expect, and nested templates must be activated separately.
Related specifications
See also
Related articles
Web Components
External resources
Attributions
Portions of this content come from HTML5Rocks! article