Understanding Web Components

The modern web is evolving at a crazy fast pace, new technologies are coming up all the time, new devices are being released constantly. Companies and developers need to follow the pace and be able to move fast, iterate, adapt and evolve.

Frontend Development is a discipline that moves particularly fast, where new frameworks and tools emerge constantly so fast adaptation is essential for survival.

“It is not the strongest of the species that survives, nor the most intelligent that survives. It is the one that is most adaptable to change.”
Charles Darwin

Why components?

By dividing your code in small reusable chunks, you’re reducing complexity, by narrowing your focus into small bits at a time, you’re improving reusability, so that you don’t have to reinvent the wheel every time you want to reuse something, that you or someone else has already done.

So it seems like a great concept, to have a set of reusable components, that are tested and ready to use, that we can group together in order to create bigger ones, transforming them into fully functional web apps.

“Treat your code like Lego; many smaller, simpler chunks can be combined and arranged to make a huge variety of structures. With a box of assorted Lego pieces you could build a car, or an airplane, or the Eiffel Tower, or Big Ben, or anything! All by combining the same little tiny pieces in different quantities, in a different way, and in a different order.”
Nicolle Sullivan

Why Web Components?

As the complexity of web applications grows, the need for modular code has also risen, if you’ve worked in a medium to large scale application, you’ve probably already made an attempt to divide your code into components. Or if you’re using a client side javascript framework, you’ve probably already created components of some kind, Angular, React, Ember, all have components, although each one thinks about components in its own way.

As we try or change to new frameworks (and in javascript new frameworks seem to appear every week) we need to redo all of our work again, wouldn’t it be really nice, if all of our components were built, using the same native core technologies, and reusable across all frameworks. Web Components make this possible by providing us with the tools to standardize and encapsulate our component construction. It’s even possible to have, components from different frameworks, talking to each other under the same application.


An example from the automotive industry
The automotive industry, approximately 20 years ago had a time to market of around 60 months and was able to reduce it to around 12.
They evolved from the production line envisioned by Ford, to an assembly line of finished components. These components are usually made by other companies, which have their own assembly lines.
So in order to make a car in one plant, it’s engine and transmission must be delivered from the plants where they were assembled.This way car companies can assemble their cars while more components are being created.
This allows manufacturers to specialize and optimize their processes and techniques, by narrowing their focus and reducing their scope, which would otherwise be too time consuming or expensive for car manufacturers.
For example the door components manufacturer can spend more time optimizing their processes and technologies to build better mirrors and security systems, while the motor manufacturer can focus on creating better and more efficient motors.
Car companies today also need to create and offer lot’s of different models, so they did something called platform sharing. In this system a car company designs its cars to share their parts, it is more efficient, makes production easier and gives customers what they want.

Diving into Web components

Web components are an umbrella term, to designate and group together, four different W3C specifications, namely:

  1. Custom Elements,
  2. Templates,
  3. Shadow Dom,
  4. HTML Imports.

Custom Elements:

Give you the ability to create your own native like HTML tags ending the so called ‘div soup’. This allows you to create more semantic and expressive HTML, it also gives you the power to extend, new and existing elements, adding extra functionality to them.

Custom elements give you the power to create your own per element API.

One mandatory rule though, your element’s name must contain a dash (-). This happens because, there needs to be a way to distinguish, Custom Elements from regular ones, but also to prevent naming collisions when new elements are added to native HTML. So, native elements will never have a dash in their naming, Custom Elements all must have a mandatory dash.

Basic Usage

//instantiate in HTML
<card-item></card-item>
//create your element and it's prototype in javascript
var proto = Object.create(HTMLElement.prototype, {
alert :{
value:function(){
alert("I'm a Custom Element");
}
}
});
var cardItem = document.registerElement('card-item', {
prototype: proto
});
var myCard = document.querySelector('card-item');
myCard.alert();

HTML Templates:

This is native client side templating. HTML templates allow you to create inert bits of markup, that you can inject with dynamic content, no more script tag hacks or hidden div’s for templates, we now have a native and more secure way to do this, and it gets better, any resource declared inside the template is inert.

Until you activate your template, styles, scripts or any images declared inside it won’t run and DOM elements can’t be traversed.

<template id=’myTemplate’>
<!- — css will only be loaded when the template is activated →
<style>
.text{
color:red;
}
</style>
<!-— script will only be loaded when the template is activated -->
<script>
alert("I’m on a template!!!");
</script>
  <p class='text'>Hi!</p>
</template>
//Activating the template:
//select your template element
var t = document.getElementById(‘myTemplate’);
//create a deep copy of it’s content
var clone = document.importNode(t.content,true);
//append it to the document body
document.body.appendChild(clone);

Shadow DOM

Allows encapsulation of markup and styles in a separate DOM tree, this is what will allow our components to be fully encapsulated. The DOM tree, when using native technologies, does not, have the concept of encapsulation. This means that styles in your css might conflict, because everything is global in css, id’s might overlap and different rules in different files might be affecting the same element in different ways. Shadow DOM is here to fix these problems.

Shadow DOM in the wild

You can see a live example of Shadow DOM usage, by inspecting a video tag(<video></video>), yes, browser vendors have been using Shadow DOM to encapsulate their native elements.

Using chrome dev tools you can turn Shadow DOM visibility on :
(settings/Elements/Show user agent shadow DOM)

Then by inspecting a video element you should be able to see its Shadow Root:

Shadow DOM creates a separate DOM tree encapsulated from your ‘Main Tree’, which with the arrival of Shadow DOM is now known as Light DOM.

In order to create Shadow DOM you need a Shadow Host, which is the element that has the Shadow DOM associated to it, then you create the Shadow Root which is the content of the Shadow DOM

Shadow DOM Architecture

You might be confused with lot’s of new terms coming up by this stage, so let’s review:

Light Dom — Main DOM tree;

Shadow Dom — Separate encapsulated DOM tree;

Shadow Host — Element that contains Shadow DOM;

Shadow Root — Content of the shadow DOM;

Building Shadow DOM

First things first, create a Shadow Host, the element that will have it’s content encapsulated by a Shadow DOM

<div id=”shadowHost”></div>
//select shadow host element
var host = document.querySelector('#shadowHost');
//create shadow dom
var root = host.createShadowRoot();
//create content to be appended to shadow dom
var div = document.createElement('div');
div.textContent = "i'm going to a shadow dom";
//append content to shadow dom
root.appendChild(div);

HTML Imports

Bundle resources in a html file, load execute and resolve it’s dependencies.

This new feature is not just a way to load components and it’s dependencies, but it’s also a way to load resources in a easy and clean way. Html Imports, are meant, to be a way to import HTML documents into other HTML documents, but they don’t limit you to just that, allowing you to import everything that can go into an HTML document such as CSS and Javascript.

Loading bootstrap with HTML Imports

Create a new html file, let’s call it ‘bootstrap.html’, and add bootstrap dependencies to it

//bootstrap.html file
<link rel=’stylesheet’ href=”bootstrap.min.css”>
<link rel=’stylesheet’ href=”fonts.min.css”>
<script src=”bootstrap.min.js”>
//In your app load the resources with an html import
<link rel=”import” href=”bootstrap.html”>

Wrapping Up

These are the very basics of the four specs, that in aggregation constitute what we now know as Web Components. With this four core technologies you can see that we finally have a native way to achieve the holy grail of componentized web apps.

Composability: reuse and group components together;

Encapsulation: Isolate markup and style, so that they don’t leak into other components;

Reusability: Reuse components across applications, extend existing ones for extra functionality;

Web components are meant to be a standard, a baseline for building components for the web. Until today we’ve never had a native way to bundle together and encapsulate our HTML, CSS and Javascript.

Why learn web components?

Web components have the potential to be a major shift and improvement to the way we develop for the web, so it will require some studying and preparation, my advice is to start learning and experimenting with web components in your projects, and getting ready for the future.

Using web components today?

You can start using and experimenting with web components today. Browser support is still pretty short, only Chrome supports the entirety of the web components specifications. Luckily there are polyfills to rescue us.

Polyfill

You can get polyfills for each of the web components spec’s at https://github.com/WebComponents/webcomponentsjs

Start using Custom Elements today

Despite the still short browser support, this seems to be the best choice to start experimenting with web components .

There are already some companies using custom elements in production, such as github and net-a-porter, so if you want to start using web components in production, i would say start here. The polyfill is light and has a broad range of browser support.

Custom elements polyfill

https://github.com/WebReflection/document-register-element