Custom HTML Elements

Ashwin Kumar
3 min readMay 9, 2021

Create your own custom components using CustomElementRegistry !!!

Creating non-standard HTML Elements are fairly easy and we can use javascript to make such elements functional. Such components become an instance of HTMLUnknownElement as shown below:

The limitation is that we can’t extend the existing DOM functionalities to make the component reactive to various changes. We are also limited to accessing the components and separately binding the functionalities on each component instead of defining the standards at one place.

Reusable Custom HTML Elements:

Normally all standard components have their own constructors defined by the user-agent. All these components also extends from base HTMLElement constructor.

Custom Components are created by defining our own constructor to be built on top of existing DOM APIs. There are two ways of doing it:

Autonomous Custom Elements

The constructor of such Custom Elements are extended from HTMLElement just like all other built in components.

Customised Built-in Elements

The constructor of these components are extended from other built-in components, like extending HTMLInputElement to create a customised input.

Creating Your Own Component:

Naming Convention:

Custom Elements have to be named with hyphen(-) to avoid naming conflicts with built-in elements. Names like <custom-button> is valid but not <custombutton> .

Creating the Constructor:

We can create our custom class extending from built in component classes . The basic structure of an autonomous element is as shown below:

The constructor is called as soon as the instance is created. At this point the attributes are not attached and cannot be accessed.

The connectedCallback is called whenever the instance is added to the DOM tree. Before this callback the attributes are updated and therefore can be used to create/update the childNodes.

The disconnectedCallback is called whenever the instance is removed from the DOM.

If you want to add Observers to specific attributes you can pass those attributes list to static getter observedAttributes .

Whenever any of these attribute values change, attributeChangedCallback() is fired.

Registering the Component:

Each window Object is allocated with an instance of CustomElementRegistry which can be accessed through window.customElements .

The define() method of this customElements can be used to register a custom component as shown below:

If you’re registering a customised built-in component, a third parameter is required specifying the extension.

Defining a component that already exists will throw error. To avoid this you can check if the element already exists in the registry using get() method before registering.

Registering custom components after the DOM is loaded will work fine as the instances will be updated once the component is registered. In some cases this is preferred also to get access to child elements.

connectedCallback() does not ensure that child Elements are attached. There is no callback for this. At best you can attach a mutationObserver() or register the component after the DOM contents are loaded to access child Elements.

Usage:

The javascript way is to use the new keyword to create an instance of the class and add it to the DOM.

In html, instance creation is different, as for autonomous component can be created just like any other element, however for customised built-in components, is attribute is used to define the custom component as shown below:

Custom components require closing tag and can’t be treated as empty elements.

Here is a sandbox to test various cycles of a custom element:

Some Use Cases:

Labeled Inputs

Usually in a form, inputs are mostly accompanied with a label. We can create a custom component to create this combination and maintain it, here is small example for the same:

Custom Slider:

A slider can be created with input[type=range] however it becomes a bit difficult to maintain it’s styling accompanied with cross-browser look and feel. We can create a component for the same and register customEvents for user engagement updates:

You can explore further using the below resources. Thank you for reading!!!

--

--

Ashwin Kumar

Web Developer, JavaScript Enthusiast, Love to Code.