# Web Components

## Summary


A webpage can be built in two ways: either as a monolithic unit of HTML tags or as a composition of individual parts: header, footer, menu, main body, side panel, and so on. The latter is easier to maintain due to its modular nature. Such modular design has been in common practice on the server side where pages are dynamically generated from modular views. Web Components enables this on the client side. 

While the use of components is possible with frameworks or libraries such as Ember, Backbone, Angular or React, Web Components is a W3C standard. It relies on nothing more than HTML, CSS and JS. It can therefore work on all browsers, can complement and be reused across frontend frameworks. Libraries built on top of Web Components are also making development simpler.

## Discussion

### What exactly is a web component?

Here's one way to define a web component, 

> A component is a small, potentially re-usable set of logic, behaviors and interface elements (UI or API).

This definition is not just about the frontend element's presentation but it's also about its behaviour. Consider a clickable button. The component for this could define the styling in terms of padding, colours and fonts. It could also define the behaviour: how the styling changes on mouse hover or mouse click; what happens when mouse is clicked. Another example is an image slider. These are usually implemented using HTML, CSS, and JavaScript, all of which can be encapsulated as a custom tag for reusability. 

Web Components is being developed by W3C as a set of standards. Once fully standardized and implemented by browsers, it will change the way we design web apps.


### What are the advantages of adopting Web Components?

Here are some advantages of Web Components:

    + **Reuse**: A component is made once and can be reused across different pages, apps, or frameworks.
    + **Support**: Once fully standardized, it will work on any browser without additional libraries.
    + **Maintenance**: Since the design is modular, and components are self-contained, they're easier to maintain.
    + **Encapsulation**: Each component on the same page can potentially have different styling. We need not worry about clashing element identities. This is due to what's called *Shadow DOM*.
    + **Reliability**: Code is not spread across HTML and JS files, thereby avoiding inconsistencies.
    + **Flexibility**: Components can be written inline, imported or even compiled.
    + **Composability**: Components can use or interface with other components.

### What the main parts of Web Components?

Web Components have four enabling parts: 

    + **Custom Elements**: We can create custom HTML tags/elements and define their initialization and behaviour. These can be created using JavaScript APIs. The use of ES6 Class is recommended rather than create a prototype Object.
    + **HTML Templates**: Tag `<template>` provides a markup template that can then be reused in multiple places. Templates themselves are not displayed; only their instances are displayed.
    + **HTML Imports**: A HTML file can import another HTML file. Thus, components defined in one file can import components defined in another file.
    + **Shadow DOM**: This is an encapsulated DOM tree that's separate from the main document DOM. This encapsulation ensures that the component will work regardless of the page in which it's used.

### How should I use attributes, properties and events in my components?

In the spirit of reuse and composability, use attributes and properties for data input. Dispatch events for output. For example, if a button is clicked, dispatch an event so that other components can take appropriate action. Don't bubble events unless they have semantics. 

Use attributes to initialize. Use properties to reflect state. Every exposed attribute should have a corresponding property. Reflecting a property change to an attribute is generally not a good idea. This is because attributes are limited to string values. This means that expensive serialization and deserialization is needed to pass arrays and objects as strings via attributes. Therefore use properties instead. 

Favour declarative over imperative API. For instance, avoid changing state via method calls that don't update property or dispatch events. 


### Could you share some best practices for working with Web Components?

Here are some best practices: 

    + When defining custom elements, use prefixes before the hyphen to indicate a custom "namespace".
    + Custom elements that use unconventional names can be hard understand. Try to stay close to standard HTML tag names.
    + Don't raise exceptions from custom elements when for similar errors the native DOM itself would ignore and continue.
    + Configuration and state should be exposed in the logical DOM, not hidden in Shadow DOM.
    + Try to make your component self-contained without reliance on external frameworks. This makes it easy for others to reuse your component.More best practices are given at Google Developers site with illustrative examples. 


### How can I use Web Components with frontend frameworks or libraries?

Web Components are set to change the way we build web apps but they need not replace frontend frameworks or libraries. The two can complement each other. For example, React can be used in Web Components or vice versa. Whereas React keeps DOM in sync with data, Web Components encapsulate reusable components well. 

Use Shadow DOM to avoid conflict with frameworks that manage DOM updates and rendering. Also, VirtualDOM Abstraction Layer (VAL) gives better control over DOM along with any virtual DOM such as React or Preact.

To convert Web Components to first-class React components, react-integration can be used. Angular Elements offers custom elements but these currently have dependence on the Angular framework. 

Developers who wish to develop components that can be used across any framework can look at Ionic's Stencil, SlimJS or SkakeJS. It's been said that SkateJS enables the use of React's JSX with Web Components. For data bindings, Observables and ES6 Proxies may play well with Web Components. 

In passing, we mention that Accelerated Mobile Pages (AMP) are in fact built from Web Components and are incredibly performant. 


### What's the current state of and browser support for Web Components?

Latest status of browser support for Web Components is available on Can I Use site. Chrome and Opera offer the best support for Web Components. Browsers that don't have full native support, can use *polyfills*. A polyfill is a substitute implementation that a developer can use or import into a codebase until browsers natively start supporting that feature or technology. Web Components polyfills are available on GitHub. 

Developers can build custom components on their own. For faster development, they can also reuse components developed and shared by others as component libraries. WebComponents.org lists 1500+ reusable elements as on June 2018. Developers can also adopt component frameworks that simplify the development process. Examples of such frameworks include Google Polymer, Mozilla X-Tag and Bosonic. 

In terms of W3C standardization, `<template>` element is specified within the HTML 5.2 W3C Recommendation. Shadow DOM is specified in the DOM document. Web Components Current Status page summarizes the status.

## Milestones

1998

Microsoft creates **HTML Components (HTC)** to extend the DOM with new attributes. It relies on JScript and VBScript and Microsoft ActiveX is required. In 2011, this is discontinued and deprecated on IE10. 

2001

Mozilla introduces **XML Binding Language (XBL)**. The idea is to extend default tags with custom behaviour. XBL2 comes out in 2007. While the intention is good, implementations are not. This is eventually abandoned in 2012. 

2010

From the failure of vendor-oriented approaches, comes the idea of frameworks or libraries that can offer custom elements in a cross-browser compatible manner. In 2010, **AngularJS** is released. Likewise, **React** is born in 2011 and is used internally by Facebook. 

2011

At the Fronteers 2011 conference, Alex Russell gives a talk titled "Web Components and Model Driven Views". He explains how JS frameworks are trying to do what HTML is supposed to do. He then outlines scoped CSS, custom elements and web components. 

May  
2012

W3C publishes a working draft titled "Introduction to Web Components". 

2014

Google Chrome and Opera browsers start supporting v0 of Web Components. In 2016, the same browsers start supporting v1 of Web Components.