Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use of Template with HTML Custom Elements

I just started learning about the HTML custom elements, and through reading a series of intros, tutorials, and documentation, I think I have a good handle on how it works, but I have a philosophical question on the proper way to use or not use the <template> tag.

Custom elements give you the ability to encapsulate new functionality, simplifying the structure of your HTML document, and allowing you to simply insert a <my-custom-element>...</my-custom-element> tag instead of <div class="my-custom-element"><span class="part1">...</span><span class="part2">...</span></div>.

The class definition for the element then sets up the structure and functionality of that element. A bunch of the tutorials then describe how to use <template>...</template> and <slot>...</slot> to set up the contents of the custom element. You would then have to then include the template code in every HTML document in which you want to use the element rather than setting it up in the custom element class's constructor. Doesn't this run counter to the fact that custom elements help simplify and encapsulate functionality in a way that makes them more portable? Or am I misunderstanding the proper usage and/or placement of the template within the document?

Looking through SO, the closest I can find to addressing this is this question:

How to stamp out template in self contained custom elements with vanilla js?

But the answer essentially sidesteps this all together and says "Don't use <template>," and so doesn't really clear up my confusion.

like image 805
bjg222 Avatar asked Sep 21 '18 02:09

bjg222


People also ask

What is the use of HTML template?

The <template> tag is used as a container to hold some HTML content hidden from the user when the page loads. The content inside <template> can be rendered later with a JavaScript. You can use the <template> tag if you have some HTML code you want to use over and over again, but not until you ask for it.

What is HTML template element?

The <template> HTML element is a mechanism for holding HTML that is not to be rendered immediately when a page is loaded but may be instantiated subsequently during runtime using JavaScript. Think of a template as a content fragment that is being stored for subsequent use in the document.

What are custom elements in HTML?

Custom Elements allow web developers to define new types of HTML elements. The spec is one of several new API primitives landing under the Web Components umbrella, but it's quite possibly the most important. Web Components don't exist without the features unlocked by custom elements: Define new HTML/DOM elements.

What's the difference between Web Components and custom elements?

Web Components consist of three separate technologies that are used together: Custom Elements. Quite simply, these are fully-valid HTML elements with custom templates, behaviors and tag names (e.g. <one-dialog> ) made with a set of JavaScript APIs. Custom Elements are defined in the HTML Living Standard specification.

What is the use of template in HTML?

HTML &lt;template&gt; Tag 1 Definition and Usage. The <template> tag is used as a container to hold some HTML content hidden from the user when the page loads. 2 Browser Support 3 Global Attributes. The <template> tag supports the Global Attributes in HTML. 4 More Examples. Fill the web page with one new div element for each item in an array.

What are the types of custom elements in HTML?

Two kinds of custom elements can be distinguished: Autonomous: to this group are related the “all-new” elements that extend the HTMLElement class. Customized built-in elements: these are the ones that extend built-in elements such as a customized button built on the HTMLButtonElement. We will start at discovering the autonomous custom elements.

Should template code be included in the custom element constructor?

You would then have to then include the template code in every HTML document in which you want to use the element rather than setting it up in the custom element class's constructor. Doesn't this run counter to the fact that custom elements help simplify and encapsulate functionality in a way that makes them more portable?

What is the use of my custom element?

Custom elements give you the ability to encapsulate new functionality, simplifying the structure of your HTML document, and allowing you to simply insert a <my-custom-element>...</my-custom-element> tag instead of <div class="my-custom-element"><span class="part1">...</span><span class="part2">...</span></div>.


2 Answers

Actually <template> elements can be imported from another document via HTML Imports, along with the Javascript code that will define the custom element:

<link rel="import" src="my-custom-element.html">
...
<custom-element></custom-element>

So it doesn't need to be included in a every HTML document. This post shows a minimal example.

HTML Imports are implemented only in Chrome and Opera. If you want to use them in the with Firefox and Safari you'll need to use the HTML Imports polyfill.

On the other hand and for the moment, Mozilla and Apple don't intend to implement HTML Imports natively in their respective browsers. Therefore they recommend to define custom elements with pure Javascript modules (with import or <script src="...">), and promote template literals strings instead, which offer some advantages (variables, functions), but are sometimes more complicated to code in an IDE (because of their string representation).

Maybe in the future standard HTML modules will be adopted by all browsers, and <template> will come back in the spotlight...

Note that without HTML Imports you can still import yourself some HTML documents with fetch():

fetch( "template.html" )
    .then( stream => stream.text() )
    .then( text => 
        customElements.define( "c-e", class extends HTMLElement {
            constructor() {
                super()
                this.attachShadow( { mode: 'open'} )
                    .innerHTML = text
            }
        } )
    )

Update 2019

HTML Imports won't be supported natively after Chrome 73. You should then use the other solutions listed above (the polyfill, an alternate module loader, JS import, or a direct download with fetch).

like image 178
Supersharp Avatar answered Oct 23 '22 20:10

Supersharp


Disclaimer: I'm an author of the rich-component library mentioned below.

After some time of experimenting with custom elements and recently raising a full blown project based solely upon them I'd like to share my insights on this:

  • any component tiny as it is, is a candidate to grow to some beast
  • HTML part of it may grow to a point where it is very non-convenient to keep it within JS
  • do use template, built and parsed once and from that point cloned and injected into the shadow root - this is the same best practice as to use document fragment instead of mutating a living DOM
  • if the template contents should be changed from component's instance to instance - some kind of data binding framework may be used, and if minimalist approach on those is taken - it might still be easier and more performant to deal with a cloned-from-template document fragment than operate on string or template literals

In order to not write the same dozens of lines over and over again I've prepared rich-component library, which:

  • normalizes some API for template provisioning and all those 'clone template, create shadow, inject template's content into it' lines of repeating code
  • known to fetch html contents when html URL is provided
  • caches the templates so the fetch is done only once
like image 20
GullerYA Avatar answered Oct 03 '22 03:10

GullerYA