This section describes Web Components related technologies

1. Custome elements

The technology is relatively easy to understand; As the name implies, a custom tag is an HTML element, such as

,

, or

, but we can name it ourselves through the browser API. Custom elements are just like standard HTML elements (their names are in Angle brackets), except that they always have a dash, such as

or

. This is done to prevent conflicts with native built-in tags.

Custom elements contain their own semantics, behaviors, and tags that can be shared between the framework and the browser.

class MyComponent extends HTMLElement {
  connectedCallback() {
    this.innerHTML = `<h1>Hello world</h1>`
  }
}

customElements.define('my-component', MyComponent)
Copy the code

In this example, we define our own HTML element < my-Component >. Granted, it doesn’t do a lot of work, but it’s a basic building block for custom elements. All custom elements must extend HTMLElement in some way before they can be registered and used in the browser.

There is no reliance on any third party framework in the code, and browser vendors are working on backward compatibility with the specification as they upgrade, almost guaranteeing that components written to the specification will not be affected by disruptive API changes. More importantly, these components often work with the most popular frameworks available today, including Angular, React, Vue, and others. More and more

2. Shadow Dom

The Shadow DOM is a encapsulated version of the DOM. This allows developers to effectively isolate DOM fragments from each other, including any content that can be used as CSS selectors and the styles associated with them. In general, anything in the scope of the document is called the Light DOM, and anything in the Shadow Root is called the Shadow DOM.

When using the Light DOM, you can use document.querySelector(‘selector’) to select an element, or element.querySelector(‘selector’) to select the child elements of any element;

Similarly, children of the shadowRoot can be selected by calling shadowroot.queryselector, which is a reference to a document fragment; The difference is that the child elements of the shadow root cannot be selected from the Light DOM. For example, if we have a shadowRoot that contains

In this respect, the Shadow DOM works a bit like the

If you’ve ever written components that overweight the same ID, or rely on CSS-in-JS tools or CSS naming strategies (such as BEM), then Shadow DOM has the potential to improve your developer experience.

Imagine this scenario:

<div>
  <div id="example">
    <! -- Pseudo-code used to designate a shadow root -->
    <#shadow-root>
      <style>
      button {
        background: tomato;
        color: white;
      }
      </style>
      <button id="button">This will use the CSS background tomato</button>
    </#shadow-root>
  </div>
  <button id="button">Not tomato</button>
</div>

Copy the code

The HTML is completely valid except for the pseudocode of <#shadow-root>, which is used here to delimit the shadow DOM boundaries. To attach a shadow root to the above node, we can run the following code:

const shadowRoot = document.getElementById('example').attachShadow({ mode: 'open' })
shadowRoot.innerHTML = ``
Copy the code

The shadow root can also contain other external node content by using the

element. Using slots places user content from the external node to the specified location on the shadow root element.

3.template

Appropriately named HTML

<template id="book-template">
  <li><span class="title"></span> &mdash; <span class="author"></span></li>
</template>

<ul id="books"></ul>
Copy the code

The above example doesn’t render anything until the script uses the template, instantiates the code, and tells the browser what to do with it.

const fragment = document.getElementById('book-template')
const books = [
  { title: 'The Great Gatsby'.author: 'F. Scott Fitzgerald' },
  { title: 'A Farewell to Arms'.author: 'Ernest Hemingway' },
  { title: 'Catch 22'.author: 'Joseph Heller' },
]

books.forEach((book) = > {
  // Create an instance of the template content
  const instance = document.importNode(fragment.content, true)
  // Add relevant content to the template
  instance.querySelector('.title').innerHTML = book.title
  instance.querySelector('.author').innerHTML = book.author
  // Append the instance ot the DOM
  document.getElementById('books').appendChild(instance)
})
Copy the code

Ostensibly, a user using a service that exploits the template API can write templates of any shape or structure that can be created later. Another page on the site may use the same service, but the template is structured like this:

<template id="book-template">
  <li><span class="author"></span>'s classic novel <span class="title"></span></li>
</template>

<ul id="books"></ul>
Copy the code

The Web Components specification is a set of low-level apis that will evolve and evolve as developers meet their needs.

In the next article, we’ll take a closer look at the HTML templates section. We’ll then move on to custom elements and the shadow DOM. Finally, we’ll look at higher-level tools and combine them with today’s popular libraries and frameworks to wrap things up.