Web Components - Introduction to the future web

SAKET KUMAR   |  16th June, 2015

Web is evolving rapidly, If we analyze heavy modern web applications they are not only complex to design but also quite difficult to develop and manage. Given the range of tools involved, amount of testing required, and the combination of libraries/frameworks used, the development process has become complex. As the application scales in terms of features, it becomes harder to maintain the code and make enhancements.

For instance, take a look at the DOM of these few popular websites:

Markup

The complex DOM structure of modern web applications is largely due to indiscriminate use of divs and spans. HTML5’s semantic markup came to rescue, but it still falls short due to following reasons:

  • We have too many similar components in our web page that fall under the same semantic structure. To distinguish them from each other, we use classes, IDs, or other attributes.

For example: 

Tabs can be a very genuine example here. This codepen contains the simplest tabs we can have - 

 

    

  • The available list of semantic tags are simply not enough to target the wide variety of components that constitute our design. As a result, we fall back to traditional tags like div or span.

Given needs of modern web and innate need of DOM structure as essential, developer community has been mulling to make things easier and one of the manifestation of such discussions led to the birth of web components support at the browser level. 

The promise of Web Components

Web components are a collection of specifications that enable developers to create their web applications as a set of reusable components. Each component lives in its self-defined encapsulated unit with corresponding style and behavior logic. These components can not only be shared across a single web application but can also be distributed on the web for use by others.

Fundamentally web components consist of 4 major specifications:

  • Custom Elements – These enable developers to create their own elements that are relevant to their design as part of the DOM structure with the ability to style/script them just like any other HTML tag.
  • HTML Templates – These let you define fragments of markup that stay consistent across web pages with the ability to inject dynamic content using JavaScript.
  • Shadow DOM – This is designed to abstract all the complexities from the markup by defining functional boundaries between the DOM tree and the subtrees hidden behind a shadow root.
  • HTML Imports – Similar to import one CSS file into another, these allow you to include and reuse HTML documents in other HTML documents.

Links if you want to dive deep into understanding web-components

Custom Elements

They allow web developers to define new types of HTML elements.

Web Components don't exist without the features unlocked by custom elements:

  • Define new HTML/DOM elements
  • Create elements that extend from other elements
  • Logically bundle together custom functionality into a single tag
  • Extend the API of existing DOM elements

Registering a custom element

There are 3 simple steps to register a custom elements:-

  • Create prototype of existing HTMLElement object.
  • Add any custom markup, style, behavior via it’s created lifecycle callback.
  • Register the element name, tag name and prototype with the document.
<my-element></my-element>
 
var proto = Object.create(HTMLElement.prototype);
proto.createdCallback = function() {
  this.textContent = "Hello, this is my-element !!";
};
document.register('my-element', {
  prototype: proto
});

Lifecycle callback methods

createdCallback - an instance of the element is created

  • attachedCallback - an instance was inserted into the document
  • detachedCallback - an instance was removed from the document
  • attributeChangedCallback(attrName, oldVal, newVal) - an attribute was added, removed, or updated

All of the lifecycle callbacks are optional. Following is the diagram showing the processing of lifecycle callbacks in custom elements. 

Lifecycle

Resources for Custom Elements

HTML Templates

HTML Templates are another new API primitive that fits nicely into the world of custom elements.

The <template> element allows you to declare fragments of DOM which are parsedinert at page load, and instantiated later at runtime. They're an ideal placeholder for declaring the structure of custom element.

Example: registering an element created from a <template> and Shadow DOM:

<template id="mycustomtemplate"><style type="text/css">
<!--/*--><![CDATA[/* ><!--*/
p { color: orange; }
/*--><!]]>*/
</style><p>I'm in Shadow DOM. My markup was stamped from a template.</p>
</template>

Resources for HTML Templates

Shadow DOM

Shadow DOM is a powerful tool for encapsulating content. Use it in conjunction with custom elements and things get magical!

Shadow DOM gives custom elements:

  • A way to hide their guts, thus shielding users from gory implementation details.
  • Style encapsulation.

Creating an element from Shadow DOM is like creating one that renders basic markup. The difference is in createdCallback():

var XFooProto = Object.create(HTMLElement.prototype);
XFooProto.createdCallback = function() {
  // 1. Attach a shadow root on the element.
  var shadow = this.createShadowRoot();
  // 2. Fill it with markup goodness.
  shadow.innerHTML = "<b>I'm in the element's Shadow DOM!</b>";
};
var XFoo = document.registerElement('x-foo-shadowdom', {prototype: XFooProto});

Resources for shadow DOM

HTML Imports

HTML Imports, part of the Web Components cast, is a way to include HTML documents in other HTML documents. You're not limited to markup either. An import can also include CSS, JavaScript, or anything else an .html file can contain. In other words, this makes imports a fantastic tool for loading related HTML/CSS/JS.

Include an import on your page by declaring a :

The URL of an import is called an import location. To load content from another domain, the import location needs to be CORS-enabled:

<!-- Resources on other origins must be CORS-enabled. -->

Resources for knowing more of HTML Imports

Use Web Components today

The specifications mentioned above are quite new and it is hardly surprising to know that browser support is not very good. But, thanks to the Polymer library, created by the awesome folks at Google, we can use all these features in modern browsers today. Polymer provides a set of polyfills that enables us to use web components in non-compliant browsers with an easy-to-use framework. Polymer does this by:

  • Allowing us to create Custom Elements with user-defined naming schemes. These custom elements can then be distributed across the network and used by others with HTML Imports.
  • Allowing each custom element to have its own template accompanied by styles and behavior required to use that element.
  • Providing a suite of ready-made UI and non-UI elements to use and extend in your project.

In my coming blogs we will get deep into each of the specs of the Web Components and check out what role does polymer play in each of them to make the use of Web Components more easy and relaible.

Looking for a Drupal partner ?

We are drupal 8 ready