Extension number

For web components custom elements are a piece of a larger puzzle. Continuing in the analogy, the elements you create with the API are small pieces themselves; finer chunks of features you can amass with a class and a most helpful keyword: extends.

extends

It is possible to extend and inherit from a generic HTMLElement interface, as well as more specific structures, so that you are able to enhance solid markup. And quite interestingly, it is possible to go even further than that. To see how, consider the staple of every UI library, a soulless button.

<button>Click me</button>

Included in the page, the element frames the content in the familiar control. You are able to style the widget with CSS, and respond with JavaScript to a wide array of interactions, baked-in by default.

With custom elements, we can continue on top of this trusted base. The key is the is attribute, where you specify the tag name of a would-be element.

<button is="pestering-button">Click me</button>

The connection to the custom element is then in a script, parallel to the document. Here you can define a class extending the appropriate interface, HTMLButton, and a constructor function to replicate the button’s core features.

class PesteringButton extends HTMLButtonElement {
	constructor() {
		super();
	}
}

To showcase the effect of the custom element, and add some questionable character, we add an exclamation point right after the text.

super();
this.textContent += '!';

Past the class, then, we associate the class to the markup with customElements.define.

customElements.define('pestering-button', PesteringButton, {
	extends: 'button'
});

The function requires three whole arguments:

  1. the string for the imaginative tag name

  2. the authored class

  3. an object pointing to the extended node, button

And the result is likely expected, a button with a more stressful tone.

This is how you can extend an interface, but as mentioned, there’s a way to continue. Not only to build on top of standard HTML elements, but on top of other custom elements. For this, think of yet another button, even more spirited than the first one.

<button is="extra-pestering-button">Click me</button>

In the script you can define a class which extends that of the previous custom element.

class ExtraPesteringButton extends PesteringButton {
	constructor() {
		super();
	}
}

The super function in the constructor method has the same purpose as in the first snippet, to recreate the inspiring class, and this means the exclamation point is indeed included.

On top of the mark we add two more expletives.

super();
this.textContent += '!!';

After the fact, finally, we define the custom element with the same formula. Once again you need to refer to the hyphenated name and the class. And once again, the exact object explaining the original node.

customElements.define('extra-pestering-button', ExtraPesteringButton, {
	extends: 'button'
});

The extends property requires a reference to the antique element, and the code works, once again, as you might expect.

A pointless showcase, perhaps, but in the larger scope of custom elements, in the all-encompassing domain of web components, the proof of concept for a more complex system. You can build a collection of components in increments, in modular fashion. And similar to a UI library, can focus next on the styling of the smaller pieces.