What are Web Components?
The core concept of a Web Component is similar to that of components in frameworks such as React, Angular or Vue. It is a reusable UI building block that encapsulates all the HTML, CSS and any JavaScript-based logic required to render it. The big difference is that instead of relying on a specific JavaScript framework it leverages technologies natively provided by the browser so that your Web Components are framework agnostic. The technologies that Web Components leverage from the browser are features such as Custom Elements, Shadow DOM, ES Modules and HTML Templates.
The Custom Element API allows you to define new HTML tags with associated templates, styling and logic. The styling can be encapsulated using the Shadow DOM which makes your component ignore any styles applied outside of it.
If you are interested in getting more in-depth on the four features that Web Components leverage from browsers, I would recommend that you read the latest from webcomponents.org.
Benefits of Web Components
Building a reusable component library using Web Components allows you to adopt to the ever evolving JavaScript frameworks landscape.
Web Components can be a great solution for companies that use different JavaScript frameworks across different sites and would like to keep the look and feel of those sites consistent. A good way to achieve this consistency is through a Design System. A Design System allows you to share UI components across multiple teams or projects. This enables you to deliver a consistent brand and user experience at scale. While there are many different tools and frameworks that you can use to build a Design System, Web Components are a particularly good option for organizations that use different tech stacks across different teams or projects. Instead of developing multiple render targets for your Design System you can build a component library that can be consumed across all the different tech stacks. As designs iterate and you want to deliver updates to the Design System, instead of having to revise say the React and Angular component, you only need to update the one Web Component.
Web Components can also be good for future proofing your site. For example, say that your site currently uses React and you have built all your components in React. Then in the future, either due to business decisions, technology advances or maintainability issues, your company decides to switch to a different JavaScript framework. In that case, your company would have to develop new components in this new framework. Alternatively, if your company’s component library was built using Web Components, that library can be re-used in the new JavaScript framework thus saving costs and time.
These are just a few of the key benefits that explain the growing popularity of Web Components.
Will it work in any browser?
The short answer is yes, with the appropriate polyfills. Evergreen browsers such as Chrome, Firefox and Safari support most features natively. Edge is currently in the process of building native support for Web Components.
However, there is a bit of a caveat in Safari: autonomous custom elements(custom elements extending HTMLElement) will work but not customized built-in elements (custom elements extending built-in elements such as HTMLButtonElement), but the good news is customized built-in elements will work in Safari with an appropriate polyfill like document-register-element.
Below is the break down of what major browsers support Web Components.
Web Component support in major browsers.
How do you build a Web Component?
There are several ways to build a Web Component depending on how complex you need it to be. Web Components can be made using plain CSS, HTML and JS without a build process. A good resource to go over before trying to build Web Components yourself is this documentation by Google. It provides a very good explanation of how to build a Web Component from scratch with a few examples. Below is an example of how a simple Web Component can be built in a JavaScript file and then using that component in the index.html file.
Code and demo in CodeSandbox for making a Web Component using vanilla JS.
There are also many libraries out there that help make building Web Components easier. They handle most of the complexity associated with data bindings and event listeners. Many libraries also offer additional lifecycle methods available with the standard Web Component specifications to give you more control over your Web Component.
Here are a few of the libraries:
LitElement: Developed by Google folks, this library uses lit-html to render into the element’s Shadow DOM and also provides an API to help manage element properties, attributes and lifecycles. It also loads polyfills to support natively unsupported browsers for web components such as IE11 and Edge.
StencilJS: Built by the Ionic framework team, this library allows you to write your web components with JSX as well as an API to help manage element properties, attributes and lifecycles. It also loads polyfills to support IE11 and Edge.
Hybrids: Unlike the two libraries above, Hybrids uses plain objects and pure functions syntax over classes syntax when composing web components. It also uses polyfills to support IE11 and Edge.
Web Components and Accessibility
Any elements rendered on the Shadow DOM is accessible by assistive technologies because it is also included in the accessibility tree. There are a few things to keep in mind to ensure that your custom components will be fully accessible.
Let’s take the built-in element button as an example. The buttonelement has built-in accessibility for things like keyboard interaction and highlighted focus because it has an implicit role of “button”. However, if you decide to make a Web Component that acts like a button but not use the built-in element button you will have to make sure that you include information like role, aria-labels, tab-index, keyboard interactions in your element. There is a very good article by Rob Dodson on ‘The future of accessibility for custom elements’. He proposes the use of the Accessibility Object Model for defining a custom element’s semantics directly in the accessibility tree.
In Part 2 of this blog, I will be using LitElement to demonstrate how to build a Web Components library and will be talking about how to integrate them into a React app and an Angular App. Stay tuned!