Check out a free preview of the full Vanilla JS: You Might Not Need a Framework course:
The "Overview & Custom Elements" Lesson is part of the full, Vanilla JS: You Might Not Need a Framework course featured in this preview video. Here's what you'd learn in this lesson:

Maximiliano briefly discusses an overview of web components and their associated set of standards, including, custom elements, HTML templates, shadow DOM, and declarative shadow DOM. Custom element attributes, lifecycle, slots, and custom builtins are covered in this segment.

Get Unlimited Access Now

Transcript from the "Overview & Custom Elements" Lesson

[00:00:00]
>> But now it's time to fill these pages with something more interesting. And that's the time to cover one of the big topics of today, but you will see it's not difficult, that's Web Components. We're going to make each page its own component. Instead of just writing HTML, instead of h1, we could just, put everything there, but it's better to create a component.

[00:00:26] What's a Web Component? A modular reusable building block for web development. It encapsulates a set of related functionality and user interface elements. If you're coming from a library, you know what a component is. Most of the UI libraries out there, they're using the same concept, React, Angular, they all have components, okay?

[00:00:49] So on some libraries we also have components that are not user interface based. Mostly on React, for example, you have high order components. Another idea here is more related to user interface. You can also create components without user interface, it's possible, but not so common for web components.

[00:01:14] So in short, it's your own custom HTML tag element, that's the idea. So we can create our own HTML elements. Web Components is actually today compatible with every browser. So that wasn't the case five years ago, but it is right now. It's not actually one standard or one spec, so it's like an umbrella term.

[00:01:38] Actually we have a set of standards that can work separately or together, and that's what we know as a web component. The first one is known as custom elements, we will go one by one in details. HTML Templates, Shadow DOM, and there is another one called Declarative Shadow DOM that we won't use.

[00:02:04] Because it's really new in terms of full compatibility, that means Safari has just added support for it. So maybe we still need to wait a little bit to get more Safari users into it. It's actually similar to the idea of components of most of the libraries. And here comes the part that some of you won't like, we have freedom of choice on how to define them and use them.

[00:02:32] There is no single way to create the Web Component. You understand the four, or the three APIs that we will use, Custom Elements, Templates and Shadow DOM, why? When you understand those, you're free to decide how to set up them, how to define them, okay? So let's start with Custom Element.

[00:02:54] Custom Element is a way to define a new reusable HTML element with custom behavior and functionality using JavaScript. But basically, it's the one that register within the browser a new tag name, okay? That's all, this is how it works, it's not really complicated. We need to create the class with a name, any name will work, extending from HTMLElement, that's the interface that is the base of DOM elements.

[00:03:23] And not just HTMLElement, you can extend from HTMLHeadingElement, TableElement. So you can extend from anyone, OOP, object-oriented programming, you are inheriting from. You typically have a constructor that must call super. And that's all in terms of the class. And then you use the customElements API, that is a global object in compatible browsers, where you define an element name as a string.

[00:03:53] And the class, that is your class name, that's all. After you do that, you are free to use that element in HTML directly or to create one using the DOM APIs. So it's not complicated. So maybe you're thinking, but I like React with functions, and yeah, well, here it must be a class extending HTMLElement, okay?

[00:04:22] But you can create a factory function that returns one of those. So again, in terms of simplicity of the API, you can make it simpler if you want to, if you need to. So one important thing that you saw there is that the tag that we define must contain a hyphen, it's mandatory.

[00:04:45] And this is to assure future compatibility. Because if we call it, I don't know, country selector, whatever, well, that's too word, but let's say countries, how can we sure that HTML8 will not have a countries HTML tag? So we cannot be sure for the future, and the idea is to create content that will be future-proof.

[00:05:11] And the way to do that is the hyphen. It's like the W3C said, in the future, we won't define HTML tags with a hyphen. So if it has a hyphen, it's a custom thing, okay, that's the idea. So these elements can contain attributes, and typically we define the attributes with data-.

[00:05:34] So for example, I can have an element with a language property or attribute, and we use data-language. And from inside, we just use dataset, that object, that API, to access the values. It's an object, okay, we are the element now. There is a lifecycle that is simpler compared with other frameworks or libraries, but there is one.

[00:06:03] Well, we have the constructor where we typically set up the initial state and event listeners for this. And then we have connectedCallback. The terminology is kind of weird compared with other frameworks. But this is actually when the element is added to the document. So this is where we know that our component is now in the document.

[00:06:27] And because we have connectedCallback, we have disconnectedCallback. We have a question, yeah.
>> Is there a way to send an object or something without having to serialize it, to add it to the Web Component?
>> You're talking about this here. The question is that, if the situation happens in HTML or in JavaScript.

[00:06:55] If it happens in JavaScript, because it's an object and you are extending from, you can create your own properties. And even now on modern JavaScript, you can even have a private property and then setters and getters and all that stuff. The problem is with HTML, HTML only accepts strings.

[00:07:17] So if you are going to write that property, that added in HTML, you must express that as a string. So you can't use something like JSX where you open curly braces and you put the Bible inside, in this case, HTML must be a string. But from a JavaScript point of view, because it's a class, so in this class, you can add normal properties, JavaScipt properties.

[00:07:45] And they can be functions, they can be whatever you want, but you won't be able to define values from HTML. So for the lifecycle, then connectedCallback, to be honest, is the one that we will use most of the time. Actually, what we are doing is we are overriding that function from the super class on the super class is empty, so we don't even need to call super.

[00:08:09] You can, [LAUGH] but it's empty. It's just like a hook that we have within custom elements to do something when that component enters the DOM or removed from the DOM. adoptedCallback, it's a weird name, this is when your component is moving from one document to another document. And at first, we don't understand how's that a possibility, okay?

[00:08:38] So it's not like we're moving from one tab to another tab in the browser. Because in that case we're talking about two different navigations, two different contexts. It's not that, it's not drag and drop as well, it has to do with the next step known as DOM shadow, okay?

[00:08:56] We will get there, you will understand what option is there. So then we have attributeChangedCallback that is pretty simple to understand based on the name. So every time there is a change in an attribute, that function will be executed. And you will receive the name of the attribute, the old value, and the new value.

[00:09:19] Okay, and also we have something known as a slot. In our case, we won't use too much, what's the slot? The slot is what, for example, is called children or child props in other languages. It's when you have your element in the template, so here I have my element, and I have other elements within my tag.

[00:09:50] You can receive that, and it's called the slot. And actually, you can have multiple slots. So you can let the consumer of your component to define different slots. Like this is the header, this is the main content, and this is the footer, okay? So you can have different slots, and then decide what to do with those slots within your web component, okay?

[00:10:15] Now, just for you to know. And there is also something interesting, but it's not available in Safari. So this is kind of the part that we start saying don't use it yet, it's called customized builtins. The idea is that instead of using the tag name, we can use other tags, like normal tags, and express, I want this as my element.

[00:10:43] So it's like expressing to the browser, hey, this div, I want you to use that class. So create an instance of that class instead of the standard div, okay? It can be a list, ul. So then you say ul is equals, and the name of your custom element.

[00:11:02] This is not available in Safari today, so in Safari you have to use my-element as as a tag. So that's one part, custom elements.