I have been reading the documentation on the <template>
tag, and I can't seem to understand how it is different from simply using a <div>
that is display: none;
Documentation: template tag
<template>
example
<template id="productrow">
<tr>
<td class="record"></td>
<td></td>
</tr>
</template>
VS
<div>
example
<div id="productrow" style="display: none">
<tr>
<td class="record"></td>
<td></td>
</tr>
</div>
- On a low level, how does the browser handle these 2 examples differently?
- Are certain JS methods or HTML attributes different or not available?
PS: I am aware of browser compatibility differences
I have been reading the documentation on the <template>
tag, and I can't seem to understand how it is different from simply using a <div>
that is display: none;
Documentation: template tag
<template>
example
<template id="productrow">
<tr>
<td class="record"></td>
<td></td>
</tr>
</template>
VS
<div>
example
<div id="productrow" style="display: none">
<tr>
<td class="record"></td>
<td></td>
</tr>
</div>
- On a low level, how does the browser handle these 2 examples differently?
- Are certain JS methods or HTML attributes different or not available?
PS: I am aware of browser compatibility differences
Share Improve this question edited Jun 20, 2020 at 9:12 CommunityBot 11 silver badge asked Apr 25, 2018 at 18:19 PrivatMamtoraPrivatMamtora 2,1522 gold badges21 silver badges29 bronze badges 4 |3 Answers
Reset to default 14Consider:
<template>
<style>
body: { background-color: black; }
</style>
<script>
alert('hello');
</script>
<audio src="alert.wav" autoplay></audio>
</template>
And:
<div style="display: none;">
<style>
body: { background-color: black; }
</style>
<script>
alert('hello');
</script>
<audio src="alert.wav" autoplay></audio>
</div>
Are these going to behave the same when the browser renders them? (Spoiler: no.)
To address your specific questions, though:
- On a low level, how does the browser handle these 2 examples differently?
For one, the HTML inside a <template>
does not become DOM elements that are children of the <template>
. It becomes children of an "inert" DocumentFragment (indirectly; this is a simplification) where they exist as nodes but do not "do" anything, as in the example above.
In addition to being "inert," the template contents have no "conformance requirements." Your <tr>
example above is a good one. See what happens here:
const template = document.querySelector('template');
const div = document.querySelector('div');
console.log('template.innerHTML is', template.innerHTML);
console.log('div.innerHTML is', div.innerHTML);
<template>
<tr>
<td class="record"></td>
<td></td>
</tr>
</template>
<div style="display: none">
<tr>
<td class="record"></td>
<td></td>
</tr>
</div>
In a normal document, a <tr>
can't be a child of a <div>
, so the browser just removes it. In a <template>
, that requirement doesn't exist. You would find the same with, say, <div style="{{myStyle}}">
. In a document, the browser would throw away the style
attribute because its value is invalid; in a <template>
it would not. This is what makes <template>
useful for, well, templating.
If you want to know more about how <template>
s are rendered, I suggest reading the section about it in the HTML spec. It's not easy reading, and parts may be incomprehensible, but you stand to learn a lot.
- Are certain JS methods or HTML attributes different or not available?
The <template>
element has the content
attribute, which points to the DocumentFragment discussed above.
Elements inside of <template>
can't be found by any selector in JS, so you can't accidently find them and to extract them you have to use the content
property of the HTMLTemplateElement using something like:
var clone = document.importNode(templateElement.content, true);
Also every <style>
, <audio>/<video>/...
or <script>
is parsed on page load, but doesn't run until you clone it to into the main DOM.
I found an article that explains all the differences in detail: https://www.html5rocks.com/en/tutorials/webcomponents/template/
I realize now that the <div>
example was actually, kind of a polyfill used in older browsers and has to be severely hacked to make it work as expected.
Thanks for everyone's help.
template
can go inhead
whereasdiv
cannot – Daniel A. White Commented Apr 25, 2018 at 18:22div
also hasalign
andtemplate
hascontent
. – Daniel A. White Commented Apr 25, 2018 at 18:23<template>
can hold elements which would be invalid inside of a div (like in your example). – Teemu Commented Apr 25, 2018 at 18:24<template>
allows writing good semantic code, because it's clear that it's not a regular page element. – John Ellmore Commented Apr 25, 2018 at 18:27