Crafting Your Own HTML: A Guide to Custom Elements
Let's embark on an exciting journey to create our very first custom HTML element! ๐
Introduction:
What the heck is Custom Element?
Custom elements are like building blocks for the web, allowing you to create unique and powerful components that go beyond the standard HTML elements. Unlike the ad-hoc solutions of the past, custom elements provide a structured way to define new elements and their behavior, making them a valuable tool for modern web development. ๐ ๏ธ
What is Web Components?
Web Components is a powerful suite of technologies that empowers you to create reusable custom elements. These elements come with their functionality encapsulated, ensuring they remain isolated from the rest of your code. This encapsulation allows you to seamlessly integrate these custom elements into your web apps, enhancing modularity and maintainability. Dive into the world of Web Components and revolutionize the way you build web applications! ๐โจ
Types of Custom Elements: -
Mainly there are two types of custom elements:
Autonomous custom element :
Autonomous custom elements are like standalone building blocks for your web pages. They're completely independent, not based on any existing HTML element. Think of them as custom-made Lego bricks that you can use to construct unique and interactive components. ๐งฑCustomized built-in element :
Customized built-in elements are like taking a classic Lego brick and giving it a complete makeover. They start with a familiar HTML element as a base, but you can customize their appearance, behavior, and functionality to fit your specific needs. Think of it as creating a unique version of a standard building block. ๐จ
Benefits of creating Custom Elements:
Custom elements offer several advantages for web development:
- Code Reusability:
Custom elements can be encapsulated as reusable components, making your codebase more organized and easier to maintain. ๐ฆ
Once created, custom elements can be reused across multiple projects, saving time and effort. โณ
- Improved Maintainability:
Changes to a custom element's implementation only affect that specific component, minimizing the risk of unintended side effects. ๐ง
Issues can be isolated to specific components, simplifying debugging and troubleshooting. ๐
There are even more exciting benefits to creating custom elements beyond these. ๐
Prerequisites for creating custom elements:
To effectively create custom elements, you'll need a solid foundation in the following:
HTML : Understanding the fundamental structure of HTML documents, including elements, attributes, and content. ๐
CSS : Understanding how CSS rules cascade and override each other and knowledge of CSS selectors to style custom elements and their components. ๐จ
JavaScript:
Fundamentals: A strong grasp of JavaScript programming concepts, including variables, data types, functions, and objects. ๐ป
DOM manipulation: Ability to interact with the DOM using JavaScript to create, modify, and remove elements. ๐๏ธ
Object-oriented programming (OOP): Understanding OOP concepts like classes, objects, inheritance, and encapsulation, which are essential for creating custom elements. ๐งฉ
Let's start! ๐
Creating Custom Elements:
Ready to explore custom elements? Let's get started and create something amazing! ๐
Creating an Autonomous Custom Element:
Define Your Custom Element: Start by defining a class for your custom element. This class will extend the
HTMLElement
class, giving you a foundation to build upon.// extending HTMLElement class class Car extends HTMLElement{ constructor(){ super(); // initialize element logic this._companyName = null; } }
observedAttributes
static property specifies which attributes to observe for changes.// extending HTMLElement class class Car extends HTMLElement{ constructor(){ super(); // initialize element logic this._companyName = null; } // adding observed attributes static observedAttributes = ["company"]; }
The
attributeChangedCallback
method is called whenever an attribute is changed.
connectedCallback
method is called when the element is added to the DOM.// extending HTMLElement class class Car extends HTMLElement{ constructor(){ super(); // initialize element logic this._companyName = null; } // adding observed attributes static observedAttributes = ["company"]; // attributeChangedCallback() method is used when attributes is changed attributesChangedCallback(propertyName, oldValue, newValue){ // propertyName will always be "company" due to observedAttributes this._companyName = newValue; this._updateRendering(); } // connectedCallback() method is used when the element is added to the DOM connectedCallback(){ this._updateRendering(); } }
The getter and setter methods allows us to get and set custom attributes.
andupdateRendering
method is used to updaterender
method..
```javascript // extending HTMLElement class class Car extends HTMLElement{
constructor(){ super();
// initialize element logic this._companyName = null; }
// adding observed attributes static observedAttributes = ["company"];
// attributeChangedCallback() method is used when attributes is changed attributesChangedCallback(propertyName, oldValue, newValue){ // propertyName will always be "company" due to observedAttributes this._companyName = newValue; this._updateRendering(); }
// connectedCallback() method is used when the element is added to the DOM connectedCallback(){ this._updateRendering(); }
// getter and setter methods used to get and set custom attribute. get company() { return this._companyName; } set company(value) { this.setAttribute("company", value); }
_updateRendering(){ // It is for reader. You can check this.ownerDocument.defaultView to see if something // inserted into a document with a browsing context and avoid doing // any work if not. }
}
.
.
However, it's a good idea to check `this.ownerDocument.defaultView` to ensure that the element has been inserted into a document with a browsing context before proceeding with any operations. This helps avoid unnecessary work
2. **Register Your Custom Element:** To register this class as a custom element, use the `customElements.define` method.
```javascript
// define the custom element
customElements.define("new-car", Car);
- Use Your Custom Element: Now, you can use your custom element just like any other HTML tag.
<new-car country="ferrari">This is new car.</new-car>
You can also creating new-car
element using the DOM API:
// creating using DOM API
const newCar = document.createElement("new-car");
newCar.company = "ferrari";
document.body.appendChild(newCar);
Finally, you can also creating elements using the custom element constructor:
// creating element using custom element constructor
const newCar = new Car();
newCar.company = "ferrari";
document.body.appendChild(newCar);
Creating an Customized built-in Element :
Choose Your Base Element: Start by selecting an existing HTML element that you want to customize. This could be anything from a button to a paragraph.
Here we take a<button></button>
element.<button type="button"> We take button element to Customize. </button>
Define Your Custom Element: Create a class that extends the chosen HTML element's class. This is where you'll define the unique behavior and appearance of your custom element.
In our case we takeHTMLButtonElement
class.// extending HTMLButtonElement class class ClickableButton extends HTMLButtonElement{ constructor(){ super(); // addEventListener() method for clickable button events. this.addEventListener("click", () => { // write some clickable events! }); } }
Register Your Custom Element: Use the
customElements.define
method to register your new element. Make sure to specify the base element you're extending.
Here we extendingbutton
element.// defining the custom element customElements.define("clickable-button", ClickableButton, { extends : "button" });
Use Your Custom Element: Now, you can use your customized element just like any other HTML tag.
To construct our customized built-in element from parsed HTML source text, we use the
is
attribute on a button element:
<button is="clickable-button">Click this Button!</button>
You can also creating clickable-button
element using the DOM API:
// creating using DOM API
const clickableButton = document.createElement("button", { is: "clickable-button" });
clickableButton.textContent = "Click this Button!";
document.body.appendChild(clickableButton);
Finally, you can also creating elements using the custom element constructor:
// creating element using custom element constructor
const clickableButton2 = new ClickableButton();
clickableButton2.textContent = "Click this Button!";
document.body.appendChild(clickableButton2);
console.log(clickableButton2.localName); // button (in browser console)
Keep in mind that when you create a customized built-in element , the is
attribute won't appear in the DOM because it wasn't explicitly set. However, it will show up in the output when you serialize the element:
// serializing the element
console.log(clickableButton.outerHTML); // <button is="clickable-button">Click this Button!</button>
console.log(clickableButton2.outerHTML); // <button is="clickable-button">Click this Button!</button>
Styling Custom Elements:
Styling custom elements involves applying CSS to enhance the appearance and functionality of your custom HTML components. ๐จโจ
Shadow DOM:
Encapsulation is key for custom elements, ensuring they work seamlessly across any web page without interference. Shadow DOM helps achieve this by attaching a hidden DOM tree to an element, protecting its internals from external JavaScript and CSS.
First, create a custom element and attach a shadow root to it using the attachShadow()
method. This will create a new DOM tree, separate from the main document DOM.
class CustomElement extends HTMLElement{
constructor(){
super();
// creating a shadow root for element
const shadowRoot = this.attachShadow({ mode : "open" });
shadowRoot.innerHTML = "it is a Shadowed Custom Element.";
}
}
// defing custom elements
customElements.define("custom-element", CustomElement);
// creating custom element using custom element constructor
const customElement = new CustomElement();
document.body.appendChild(customElement);
Advanced Topics:
Diving into advanced topics on custom elements, such as performance considerations and template literals, can significantly enhance the efficiency and maintainability of your web applications. ๐ Performance considerations are crucial when developing custom elements, as they ensure that your components load quickly and run smoothly. Techniques such as lazy loading, efficient rendering, and minimizing reflows and repaints can help optimize the performance of your custom elements. โก
Template literals, on the other hand, offer a powerful way to define and manipulate HTML templates within your custom elements. ๐ By using template literals, you can create dynamic and reusable templates that are easy to read and maintain. ๐
By mastering these advanced topics, you can push the boundaries of what is possible with custom elements, creating web applications that are not only powerful and feature-rich but also performant and maintainable. ๐
There are even more exciting ways to create custom elements, such as form-associated elements and with default accessible roles, states, and properties, expanding the possibilities beyond what we've discussed so far. ๐
Happy coding! ๐
Subscribe to my newsletter
Read articles from Nehal Jain directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Nehal Jain
Nehal Jain
| Tech Fanatic ๐ | Sophomore | Learning Web Development & DSA || JavaScript || NodeJS || ExpressJS || And More |