So at first it's kind of, come on.
That's the first reaction, come on.
So because the solution for this is to start adding classes to everything, right?
Generating classitis, like the illness of adding class to everything.
Well, do you understand the problem?
By default this is what happens.
But fortunately, we do have a solution for that, and
that's the third and last part of Web Components.
That's Shadow DOM.
Remember, these three aspects are completely separated.
In the timeline in history,
they were added at different moments in different browsers.
Today all of them are supporting everything.
So we're good.
Shadow DOM is a private, isolated DOM tree within a web component that is
separated from the main document's DOM tree.
You have your own DOM, your own document.
And you remember that we have this option to, like translate,
adopt an element from another document, if you were called back for that.
This is the case where you have an element that you're moving that element from
a shadow DOM to another DOM.
So, it's like having kind of an iframe, but it's not really,
the iframe has its own navigation.
In this case, we don't have navigation, just its own DOM.
And we will see that in action in a second.
So the Shadow DOM then allows more control over styling and
encapsulation of functionality of a custom element.
By default, CSS that you declare in the main DOM, in the outer DOM,
in the global DOM won't be applied to the Shadow DOM.
Also that leads to some issues sometimes.
So for example, if you define a font style, a font family,
it won't be applied automatically to Shadow DOMs,
because it's a different DOM, has its own CSS.
And CSS that you declare in the Shadow DOM applies only there, not to the outside.
There are ways with pseudo classes and pseudo elements that
let us communicate CSS between the host and the Shadow DOM.
We won't get too deep in that, okay, but just for you to know that it's possible.
The Shadow DOM can be open or closed.
And that defines the visibility from the outer DOM.
So it's like creating a private property in Java or C#, okay?
In this case, if you create an open Shadow DOM,
the main DOM can get into the Shadow DOM.
If you say closed, it cannot.
Only JavaScript from that shadow DOM can actually get that DOM.
That does make sense.
And that's a property that you use when you create the Shadow DOM.
We have a question.
Yeah.
>> Can we reference an HTML file similar to Angular?
>> That's a good question.
So the question is if we can somehow reference an external HTML file.
I will answer fully the question in a minute but for
now let's say that the quick answer is no.
And there was an API and spec for doing that and was known as HTML imports,
but let me show you how it looks like, maybe here.
And can I use HTML imports?
Looks like this.
And as you can see, at one point we used to have green, but now it's red.
So it's actually deprecated, it was removed from the spec, and
it's not gonna happen, okay.
But that was the way to include HTML documents for
other HTML documents, for example for using it as a template.
That doesn't mean that we cannot do that, in fact, we will see how to do that.
But it's not like by the API.
So there is no API or a spec to do that.
So in this case, I'm setting all the templates in the same HTML,
but we could load these templates from the outside.
How?
Manually.
How, for example, with the Fetch API,
instead of loading a JSON, you can load HTML.
Solve the problem.
Then we can think about performance.
What happens if it doesn't load?
Yeah, we need to think about lots of stuff.
But yeah, you can do that.
Okay, so Shadow DOM.
This is how you create the Shadow DOM.
You attach a Shadow DOM to the element.
So this.attachShadow typically we do that in the constructor.
And we said the mode open or close.
And typically we store that as a property of the object to use later.
It can be called root, root DOM, root Shadow, Shadow root, different names.
So then when you're going to work with your
own DOM now you don't append to this,
you do that to the shadow DOM, make sense?
Because you as web component will be part of a bigger DOM.
But now you have your inner DOM inside you.
So you need to work with your inner DOM, that's called the Shadow DOM, okay.
Now when you have a Shadow DOM,
when you have this declaration of h1, it applies only to this h1 and
not for other h1 that you may have on the okay.
Which solves the biggest issue that we saw before.
So now when you have a style declarations within a web component,
if you enable Shadow DOM, that is optional.
If you create the Shadow DOM, then Style Sheets will apply only there,
which makes a cleaner CSS code and cleaner HTML.
Because you don't need to abuse on IDs and classes,
mostly if the components is pretty simple.
Okay, makes sense?
So, answering with more information the question about where to define
the HTML for custom elements.
There are several alternatives, not one, and it's up to us to make the decision.
We can use the DOM API's and do everything by hand,
like creating the elements by hand, or in HTML.
We can use a template in the main HTML.
That's the option that seems like we have here.
We can use an external HTML file that was the question and load it with fetch.
I'll bet you're thinking well, but the first time I'm adding that element,
well then we need to wait for the HTML to load while it can be prefetched.
We do have a preload link element, I'm sure if you have used that.
So you can prefetch in your HTML, those external files.
So then when the browser needs that, it will be already in the cache.
And when you have the data that is coming from an external HTML, you can use
inner HTML, something known as a DOMParser that we won't cover in details today.
But it's actually an object with DOM API that will parse a string and
returns a document fragment that then you can inject in the real DOM.
Something like that.