Some problems that web components try to solve are:
- lack of native reusable components
- lack of semantics
- lack of style isolation
- lack of native templating in HTML
- lack of custom elements
The web components standard attempts to solve all these problems and is composed of several smaller HTML standards:
- templates: reusable HTML markup
- custom elements
- the shadow dom: encapsulate markup and styling
- imports: bundle and package HTML, js and CSS
Up until now, we have used unorthodox and unsafe ways to implement client side templates in HTML, like the common
<script type="text/mytype"> or hidden elements.
HTML Templates is the upcoming standard for implementing native templates in HTML using the new
template element. HTML templates are:
- inert, the markup within a
templatetag is not rendered nor is evaluated by the browser,
- hidden for selectors, the markup within a
templateis not part of the DOM and thus is hidden from selectors. The only way to access the contents within a template are the template APIs,
- they can be placed anywhere within a page
Once you have defined a template, you can start using it by activating it. Say we have a simple template in HTML:
<template id="tmpl-person"> <section class="person"> <p> <span class="label">Name:</span> <span class="person__name">John Doe</span> </p> <p> <span class="label">Age:</span> <span class="person__age">32</span> </p> <p> <span class="label">Height:</span> <span class="person__height">179cm</span> </p> </section> </template>
The activation process consists in cloning the template and adding it to the DOM:
// get the template var template = document.querySelector("#tmpl-person"); // clone the template var newPerson = document.importNode(template.content, /* deepCopy */ true); // add the template to the DOM var personList = document.querySelector("#person-list") personList.appendChild(newPerson);
In addition to just placing some HTML elements within the DOM you can also inject arbitrary data within a template. Once the template is cloned, you can use any DOM functions to modify its contents:
// get the template var template = document.querySelector("#tmpl-person"); // clone the template var newPerson = document.importNode(template.content, /* deepCopy */ true); // inject data newPerson.querySelector('.person__name').textContent = "Jaime Gonzalez"; // add the template to the DOM var personList = document.querySelector("#person-list") personList.appendChild(newPerson);
As a final note, if you define nested templates, you will need to clone each template explicitely in order to use it.
Custom elements attempt to solve the semantic gap between HTML that was designed to represent documents and building rich internet applications. By providing the ability to create custom elements, the custom element standard allows you to define markup with the appropriate semantics for your application.
The use of semantic markup has many advantages:
- Increases the readability of your application ( and thus speed of development and maintainability)
- Improves SEO
- Improves accessibility
And example of a custom element for a log could look like this:
<blog> <blog-post> <author>Jaime</author> <blog-header>Lalala</blog-header> <blog-content>wawawa</blog-content> <comments> <comment></comment> </comments> </blog-post> </blog>
The custom elements API allows you not only to create your own custom HTML elements but also to extend existing elements.
To create a custom element you’ll need to follow these steps:
You can also extend custom or existing elements. To extend a custom element:
To extend an existing HTML element:
Written by Jaime González García , dad, husband, software engineer, ux designer, amateur pixel artist, tinkerer and master of the arcane arts. You can also find him on Twitter jabbering about random stuff.