Introduction to Creating Web Components
Tags: webdev, tutorial, javascript, beginners
Published: 2020-01-30 02:50:58

**Subscribe to my email list now at http://jauyeung.net/subscribe/**

**Follow me on Twitter at https://twitter.com/AuMayeung**

**Many more articles at https://medium.com/@hohanga**

**Even more articles at http://thewebdev.info/**

As web apps get more complex, we need some way to divide the code into manageable chunks. To do this, we can use Web Components to create reusable components that we can use in multiple places.

Web Components are also isolated from other pieces of code so it’s harder to accidentally modify them from other pieces of code and create conflicting code.

In this article, we’ll look at the different parts of a Web Component and how to create basic ones.

Parts of a Web Component
========================

A Web Component has 3 main parts. Together they encapsulate the functionality that can be reused whenever we like without fear of code conflicts.

*   custom element — a set of JavaScript APIs that allow us to define custom elements and their behavior, which can be used as we desired in the UI
*   shadow DOM — set of JavaScript APIs for attaching the encapsulated shadow DOM tree of the element. It’s rendered separately from the main document DOM. this keeps the element’s features private, so they can be scripted without the fear of conflicting with other parts of the document
*   HTML templates — the `template` or `slot` elements enable us to write markup templates that aren’t displayed on the rendered page. They can be reused multiple times as the basis of the custom elements structure.

Creating Web Components
=======================

To create Web Components, we do the following steps:

1.  Create a class or function to specify the web component functionality.
2.  Register our new custom element using the `CustomElementRegistry.define()` method, passing the element name to be defined and the class or function which the functionality is specified, and optionally what element it inherits from
3.  Attach a shadow DOM to the custom element using the `Element.attachSHadow()` method. Add child elements, event listeners, etc. to the shadow DOM using normal DOM methods
4.  Define HTML templates using the `template` and `slot` tags. We use regular DOM methods to clone the template and attach it to our shadow DOM.
5.  Use custom element wherever we like on our page like any other regular HTML element


Basic Examples
==============

The `CustomElementRegistry` keeps a list of custom elements that are defined. This object lets us register new custom elements on a page and return information about what custom elements are registered etc.

To register a new custom element on a page, we use the `CustomElementRegistry.define()` method. It takes the following arguments:

*   a string representing the name of the element. A dashed is required to be used in them. They can’t be single words.
*   a class object that defines the behavior of the element
*   an optional argument containing an `extends` property which specifies the built-in element our element inherits from if any

We can define a custom element as follows:

```javascript
class WordCount extends HTMLElement {  
  constructor() {  
    super();  
    const shadow = this.attachShadow({  
      mode: 'open'  
    });  
    const span = document.createElement('span');  
    span.textContent = this.getAttribute('text').split(' ').length;  
    const style = document.createElement('style');  
    style.textContent = 'span { color: red }';  
    shadow.appendChild(style);  
    shadow.appendChild(span);  
  }  
}

customElements.define('word-count', WordCount);
```

In the code above, we attach a shadow DOM to our document by calling `attachShadow` . `mode` set to `'open'` means that the shadow root is accessible from JavaScript outside the root. It can also be `'closed'` which means the opposite.

Then we create a `span` element, where we set the text content to the `text` attribute’s `length` after we split the words in it wherever there’s a space.

Next, we created a `style` element and then set the content to `color: red` .

Finally, we attached them both to the shadow DOM root.

Notice that in our class, we extended the `HTMLElement` . We’ve to do this to define a custom element.

We can use our new element as follows:

```html
<word-count text='Hello world.'></word-count>
```

There’re 2 types of custom elements. They are:

*   autonomous custom elements — which are standalone and don’t inherit from standard HTML elements. We can create them by referencing the name directly. For example, we can write `<word-count>`, or `document.createElement("word-count")`.
*   customized built-in elements — these inherit from basic HTML elements. We can extend one of the built-in HTML elements to create these kinds of elements. We can use them by writing `<p is="word-count">`, or `document.createElement("p", { is: "word-count" })`.

The kind of custom element we created before are autonomous custom elements. We can create customized elements by writing:

```javascript
class WordCount extends HTMLParagraphElement {  
  constructor() {  
    super();  
    const shadow = this.attachShadow({  
      mode: 'open'  
    });  
    const span = document.createElement('span');  
    span.textContent = this.getAttribute('text').split(' ').length;  
    const style = document.createElement('style');  
    style.textContent = 'span { color: red }';  
    shadow.appendChild(style);  
    shadow.appendChild(span);  
  }  
}

customElements.define('word-count', WordCount, {  
  extends: 'p'  
});
```

Then put in our page by writing:

```html
<p is='word-count' text='Hello world.'></p>
```

As we can see, autonomous custom elements and customized built-in elements aren’t that different. The only differences are that we extend `HTMLParagraphElement` instead of `HTMLElement` .

Then we used the `is` attribute to reference the custom element instead of using the element name in the customized built-in element.


Internal vs. External Styles
============================

We can also reference external styles as follows instead of using internal styles as we had above. For example, we can write:

```javascript
const linkElem = document.createElement('link');  
linkElem.setAttribute('rel', 'stylesheet');  
linkElem.setAttribute('href', 'style.css');  
shadow.appendChild(linkElem);
```

This references styles from `style.css` . We created a `link` element just like we do in HTML and normal DOM manipulation.

Creating Web Components is simple. We just have to define a class or function for the functionality and then put it in the custom elements registry by using the `customElements.define` method.

We can extend existing elements like `p` elements or create ones from scratch. Also, we can add internal styles or reference external ones by creating a `link` element and referencing external files.