Web components: The ultimate guide
Discover the benefits of web components, how they work, and how to get started using them today.
Custom elements can also extend existing ones. It helps to save time by not having to recreate some of the behaviour that's already in the browser. This tutorial shows you how to extend the <time> element to display relative times that machines can understand.
01. Create the class
Custom built-in elements start life exactly the same as autonomous ones, but instead of extending HTMLElement, they use an existing element as a starting point.
This component uses HTMLTimeElement – the class that <time> elements use. It includes all the behaviour around the datetime attribute, including the format it expects that data to be supplied in.
class RelativeTime extends HTMLTimeElement {}
02. Define the element
Again, much like autonomous custom elements, these also need to be registered with the browser using the define method. One added detail is the third argument, which takes an options object.
For now, this object only has one key, which is used to define exactly which built-in element it customises. It takes the tag name, and will cause an error if it doesn't exist.
customElements.define('relative-time',
RelativeTime, { extends: "time" });
03. Set the time
As the components set the value of the element in multiple places, it should have a method to call that contains that logic. Inside that method, the component tells the timeago library what that time is and sets its return value as the contents of that element.
Finally, set the title attribute, which allows users to hover their cursor over the text to see the exact time being referenced.
Get the Creative Bloq Newsletter
Daily design news, reviews, how-tos and more, as picked by the editors.
setTime() {
this.innerHTML = timeago().format(this.
getAttribute('datetime'));
this.setAttribute("title", this.
getAttribute('datetime'));
}
04. Update on connection
The component can use that new method to set the time on the element as soon as it appears on the page. Customised built-in elements cannot have an attached shadow DOM. As there is no other setup required, the component does not need any constructor.
connectedCallback() {
this.setTime();
}
05. Check attribute changes
At the moment, if the page wanted to update the time programmatically, our component would not react. It does not know it should be watching for changes to the datetime attribute.
By defining observed attributes, the attributeChangedCallback will run each time one of them changes. In this case, the component can run the setTime method again.
static get observedAttributes() {
return ["datetime"];
}
attributeChangedCallback() {
this.setTime();
}
06. Add to the page
As this element is an extension of a built-in element, the implementation is a little different. To use our new element, create a <time> tag with an extra is attribute. This should match the name given when defining the component. For browsers that do not support customised built-in elements, they will display the fallback content that is inside instead.
<time is="relative-time" datetime="2019-05-
07T12:00:00+0000">
12pm on 7th May 2019
</time>
Next page: Tools and frameworks to try
Thank you for reading 5 articles this month* Join now for unlimited access
Enjoy your first month for just £1 / $1 / €1
*Read 5 free articles per month without a subscription
Join now for unlimited access
Try first month for just £1 / $1 / €1
Current page: Create a customised built-in element
Prev Page Build your own components Next Page Tools, frameworks and elements to tryMatt Crouch is a front end developer who uses his knowledge of React, GraphQL and Styled Components to build online platforms for award-winning startups across the UK. He has written a range of articles and tutorials for net and Web Designer magazines covering the latest and greatest web development tools and technologies.