The Template Element
What is the template element
Section titled “What is the template element”The <template> element holds HTML markup that is NOT rendered when the page loads. Unlike a hidden <div>, template content has no side-effects: scripts inside it do not execute, images do not load, and styles do not apply. Its content property exposes the markup as a DocumentFragment — a lightweight container of parsed nodes that lives outside the live document tree until you explicitly insert it.
Accessing and cloning
Section titled “Accessing and cloning”Use document.querySelector('template').content (or getElementById) to get the DocumentFragment. Call content.cloneNode(true) to make a deep copy with all descendant nodes included, ready to insert anywhere in the document.
<template id="card-tpl"> <div class="card"><p class="msg"></p></div></template>const tpl = document.getElementById('card-tpl');const clone = tpl.content.cloneNode(true);clone.querySelector('.msg').textContent = 'Hello from template!';document.body.appendChild(clone);Each call to cloneNode(true) produces an independent copy — mutating one clone does not affect the original DocumentFragment or any other clone.
Why templates are efficient
Section titled “Why templates are efficient”Because template content lives in an inert DocumentFragment, the browser performs no layout, no styling, and no script execution for it until you clone and insert it. The parsing cost is paid once when the page loads, and every subsequent cloneNode(true) is a fast structural copy. This makes <template> ideal for stamping many instances of the same markup — for example, list items, cards, or repeated custom elements.
Runnable demo
Section titled “Runnable demo”The custom element my-card below uses a <template> defined in the light DOM. In its connectedCallback it attaches a shadow root and appends a clone of the template’s content. Both instances share the same parsed template, demonstrating the “parse once, stamp many” pattern.
The <template> lives in the light DOM and is accessed by ID. Each my-card instance gets its own shadow root populated with an independent clone of the template content.