Web Components is a suite of different technologies allowing you to create reusable custom elements — with their functionality encapsulated away from the rest of your code — and utilize them in your web apps.
Concepts and usage
As developers, we all know that reusing code as much as possible is a good idea. This has traditionally not been so easy for custom markup structures — think of the complex HTML (and associated style and script) you've sometimes had to write to render custom UI controls, and how using them multiple times can turn your page into a mess if you are not careful.
Web Components aims to solve such problems — it consists of four main technologies, which can be used together to create versatile custom elements with encapsulated functionality that can be reused wherever you like without fear of code collisions.
- HTML templates: The
<slot>elements enable you to write markup templates that are not displayed in the rendered page. These can then be reused multiple times as the basis of a custom element's structure.
- HTML Imports: Once you've defined a custom component, the easiest way to reuse it is to keep its definition details in a separate file and then use an import mechanism to import it into pages where you want to actually use it. HTML Imports is one such mechanism, although there is controversy over it — Mozilla fundamentally disagrees with this approach and is intending to implement something more suitable in the future.
The basic approach for implementing a web component generally looks something like this:
- Create a class in which to specify your web component functionality using the ECMAScript 2015 class syntax (see Classes for more information).
- Register your new custom element using the
CustomElementRegistry.define()method, passing it the element name to be defined, class in which its functionality is specified, and optionally, what element it inherits from.
- If required, attach a shadow DOM to the custom element using
Element.attachShadow()method. Add child elements, event listeners, etc., to the shadow DOM using regular DOM methods.
- If required, define an HTML template using
<slot>. Again use regular DOM methods to clone the template and attach it to your shadow DOM.
- Use your custom element wherever you like on your page, just like you would any regular HTML element.
- Using custom elements
- A guide showing how to use the features of custom elements to create simple web components, as well as looking into life cycle callbacks and some other more advanced features.
- Using shadow DOM
- A guide that looks at shadow DOM fundamentals, showing how to attach a shadow DOM to an element, add to the shadow DOM tree, style it, and more.
- Using templates and slots
- A guide showing how to define a reusable HTML structure using
<slot>elements, and then use that structure inside your web components.
- Contains functionality related to custom elements, most notably the
CustomElementRegistry.define()method used to register new custom elements so they can then be used in your document.
- Returns a reference to the
- Life cycle callbacks
- Special callback functions defined inside the custom element's class definition, which affect its behavior:
connectedCallback: Invoked when the custom element is first connected to the document's DOM.
disconnectedCallback: Invoked when the custom element is disconnected from the document's DOM.
adoptedCallback: Invoked when the custom element is moved to a new document.
attributeChangedCallback: Invoked when one of the custom element's attributes is added, removed, or changed.
- Extensions for creating custom built-in elements
- The is global HTML attribute: Allows you to specify that a standard HTML element should behave like a registered custom built-in element.
- The "is" option of the
Document.createElement()method: Allows you to create an instance of a standard HTML element that behaves like a given registered custom built-in element.
- CSS pseudo-classes
- Pseudo-classes relating specifically to custom elements:
:defined: Matches any element that is defined, including built in elements and custom elements defined with
:host: Selects the shadow host of the shadow DOM containing the CSS it is used inside.
:host(): Selects the shadow host of the shadow DOM containing the CSS it is used inside (so you can select a custom element from inside its shadow DOM) — but only if the selector given as the function's parameter matches the shadow host.
:host-context(): Selects the shadow host of the shadow DOM containing the CSS it is used inside (so you can select a custom element from inside its shadow DOM) — but only if the selector given as the function's parameter matches the shadow host's ancestor(s) in the place it sits inside the DOM hierarchy.
- Represents the root node of a shadow DOM subtree.
- A mixin defining features that are available across document and shadow roots.
- Extensions to the
Elementinterface related to shadow DOM:
- Additions to the
Nodeinterface relevant to shadow DOM:
Node.getRootNode()method returns the context object's root, which optionally includes the shadow root if it is available.
Node.isConnectedproperty returns a boolean indicating whether or not the Node is connected (directly or indirectly) to the context object, e.g. the
Documentobject in the case of the normal DOM, or the
ShadowRootin the case of a shadow DOM.
- Extensions to the
Eventinterface related to shadow DOM:
Event.composed: Returns a
Booleanwhich indicates whether the event will propagate across the shadow DOM boundary into the standard DOM (
true), or not (
Event.composedPath: Returns the event’s path (objects on which listeners will be invoked). This does not include nodes in shadow trees if the shadow root was created with
- A placeholder inside a web component that you can fill with your own markup, which lets you create separate DOM trees and present them together. The associated DOM interface is
slotglobal HTML attribute
- Assigns a slot in a shadow DOM shadow tree to an element.
- A mixin implemented by both
Textnodes, defining features that allow them to become the contents of an
<slot>element. The mixin defines one attribute,
Slotable.assignedSlot, which returns a reference to the slot the node is inserted in.
- Extensions to the
Elementinterface related to slots:
Element.slot: Returns the name of the shadow DOM slot attached to the element.
- CSS pseudo-elements
- Pseudo-elements relating specifically to slots:
::slotted: Matches any content that is inserted into a slot.
- Fired on an
<slot>element) when the node(s) contained in that slot change.
We are building up a number of examples in our web-components-examples GitHub repo. More will be added as time goes on.
|HTML Living Standard
The definition of 'template element' in that specification.
|HTML Living Standard
The definition of 'custom elements' in that specification.
The definition of 'shadow trees' in that specification.
|Shadow DOM||Working Draft|
|HTML Imports||Working Draft|
|CSS Scoping Module Level 1||Working Draft|
In general, web components are supported well in Chrome and Opera — most features have been enabled by default for a while. Firefox has experimental support for most features, disabled by default, which looks to be enabled by default by about version 63. Safari supports a number of features, but less than the above browsers, and Edge is working on an implementation.
For browser support of specific features, you'll have to consult the reference pages listed above.
- To enable custom elements and shadow DOM in Firefox, set the