Extend HTML with custom tags and Shadow DOM

In a previous post, I explained the basics of creating custom tags. In fact, custom tags remove some of the fragility in creating great web applications. However, the quest for control does not stop. Furthermore, traditional custom tags are not enough for building performance-rich applications. For example, the number of style selectors in your code can increase with custom tags. This is just one of the many things that can cause performance issues.

One way to fix this is via Shadow DOM.

Shadow DOM works by introducing scoped styles. It requires no special naming conventions or tools. Grouping CSS with markup becomes simple with Shadow DOM. Also, this feature allows us to hide all the details about the vanilla JavaScript implementation.

Why use Shadow DOM?

Shadow DOM provides the following solutions:

  • Allows isolated elements in the DOM. Orphaned items will not be returned by queries such as document.querySelector.
  • Allows scoped CSS. Scoped CSS ensures that all style rules remain within the page. It also means simpler CSS selectors, with no naming conflicts and lots of generic classes.

Our example

To demonstrate Shadow DOM, we will use a simple component called tuts-tabs. All references in this post will point to this piece of code. To try Shadow DOM, check out the demo below:

Understanding Shadow DOM

What is a shadow DOM?

Before you start programming with Shadow DOM, you need to understand the normal DOM.

HTML serves as the backbone of a website. In minutes you can create a page. When you open that page in a browser, the DOM starts to come into play. Once the browser loads a page, it begins parsing the HTML into a data model. This data model is a tree structure with nodes. These nodes represent the elements in your HTML. This data model is easy to modify and manipulate with code.

The downside is that the entire web page or even the complex web application is treated as a single data structure. It is not very easy to debug! For example, CSS styles that target one component can end up affecting another component elsewhere in the app.

When you want to isolate one part of your interface from the rest, you can use iframeS. But iframes are heavy and extremely restrictive.

That’s why Shadow DOM was introduced. It is a powerful capability of modern browsers that allows web developers to include substructures of various elements in the DOM. These DOM subtrees do not affect the main document tree. Technically, these are known as a tree of shadows.

The shadow tree has a shadow root which is linked to a parent in the DOM. This parent is known as the shadow guest.

For example, if you have it <input type="range"> connected to a browser powered by WebKit, it will result in a slider. How come? This is a slider because one of the subtree’s DOM elements includes “range” to change its appearance and introduce functionality similar to a slider. This is an advantage that Shadow DOM offers to the card.

Woah, this is a lot of theory. Now you may want to write some code to implement Shadow DOM in your piece of code.

Detailed guide to using Shadow DOM

Step 1. Create a shadow DOM element

Use element.attachShadow() to create a Shadow DOM element.

In our example, tuts-tabyou will see this code link for creating the Shadow DOM element.

Step 2. Add content to the shadow root

Next, we will add content to the shadow root using .innerHTML. Note that this isn’t the only way to populate your Shadow DOM. There are many APIs to help you populate the Shadow DOM.

Step 3. Link a custom element to the Shadow DOM

Linking custom elements to the shadow DOM is extremely simple. Remember, when you combine custom elements with Shadow DOM, you will be able to create components encapsulated with CSS, JavaScript, and HTML. As a result, you will create a new web component that can be reused in your application.

In our example, we create a new custom element using the customElements.define(). As mentioned in the previous tutorial, the new element should have a ‘-‘ in its name. And the tuts-tabs component extends HTMLElement.

As we extend HTMLElementit is important to call super() within the manufacturer. Also, the constructor is where the shadowRoot is to be created.

Once the shadowRoot is created, you can create CSS rules for it. CSS rules can be enclosed in the file <style> tags and these styles will only have scope tuts-tab.

Step 4. Add the style to the Shadow DOM

CSS related to the tuts-tab can be written inside the <style></style> tag. Remember, all styles declared here will scope the tuts-tab web component. Scoped CSS is a useful feature of Shadow DOM. And it has the following properties:

  • CSS selectors do not affect components outside the shadow DOM.
  • Elements in the shadow DOM are not affected by selectors outside of it.
  • Styles are scoped to the host element.

If you want to select the custom element inside the shadow DOM, you can use the :host pseudo-class. When the :host pseudoclass is used in a normal DOM structure, it would have no impact. But, within a shadow DOM, it makes a big difference. You will find the following :host style in tuts-tab component. Decide on the display and font style. This is just a simple example to show you how you can embed :host in your shadow DOM.

A grip with :host is its specificity. If the main page has a :hostwill be of higher specificity. All styles within the parent style would win. This is a way to override the styles inside the custom element, from the outside.

As your CSS gets simpler, the overall efficiency of the shadow DOM improves.

All styles defined below are local to the shadow root.

Likewise, you have the freedom to introduce style sheets within the shadow DOM. When you link stylesheets within the shadow DOM, they will be found within the shadow tree. Here is a simple example to help you understand this concept.

Step 5. Define the HTML elements in the custom component

Next, we can define the HTML elements of ours tuts-tab.

In a simple tabbed structure, there should be titles that can be clicked and a panel that reflects the content of the selected title. This clearly means that our custom item should have a div with titles ea div for the panel. The HTML components will be defined as below:

Inside the panels divyou will come across an interesting tag called <slot>. Our next step is to learn more about slots.

Step 6. Using slots in the shadow DOM

Slot plays a crucial role in the Shadow DOM API. A slot acts as a placeholder within custom components. These components can be filled by your markup. There are three different types of slot declarations:

  1. You can have a zero slot component.
  2. You can create a slot with spare or empty content.
  3. You can create a slot with an entire DOM tree.

In our tuts-tabswe have one slot named for card titles and another slot for the panel. The named slot creates holes that can be referenced by name.

Step 7: Populate the slots

Now is the time to populate the slots. In our previous tutorial, we learned about four different methods for defining custom elements. Tuts-tabs uses two of these methods to create the tab: connectedCallback And disconnectedCallback.

In connectedCallback we will populate the slot defined in point 6. Ours connectedCallback will be defined as below. We use querySelector to identify the tabsSlot And panelsSlot. Of course, this isn’t the only way to identify slots in your HTML.

Once the slots have been identified, nodes must be assigned to them. In tuts-tabwe use the following tabsSlot.assignedNodes to identify the number of cards.

Even the connectedCallback is where we will register all event listeners. Each time the user clicks on a tab title, the content of the panel must change. Event listeners to achieve this can be registered in the file connectedCallback function.

Step 8: implement logic and interactivity

We will not delve into logic, how to implement tabs and its features. However, remember that the following methods are implemented in our costume tuts-tab component to switch between tabs:

  1. onTitleClick: This method captures the click event on tab titles. It helps to change the content inside the tabbed panel.
  2. selectTab: This function is responsible for hiding the panels and showing the right panel. It is also responsible for highlighting the tab that has been selected.
  3. findFirstSelected: This method is used to select a card when it is first loaded.
  4. selected: This is a getter and a setter to retrieve the selected card.

Step 9. Define the life cycle methods

Going forward, don’t forget to define the disconnectedCallback. This is a lifecycle method in custom items. When the custom item is deleted from the view, this callback is triggered. This is one of the best places to remove action listeners and reset controls in the application. However, the callback is scoped to the custom element. In our case it would be tuts-tab.

Step 10. Use the new component!

The final step is to use tuts-tab in our HTML. We can enter tuts-tab, quite easily in HTML markup. Here is a simple example to demonstrate its use.


Here we are! We have come to the end of an important tutorial where we create and use a custom element. The process is simple and proves extremely useful when developing web pages. We hope you try to create your own and share your experiences with us.

Source link

By LocalBizWebsiteDesign

Leave a Reply

Your email address will not be published. Required fields are marked *