Custom Shadow DOM
📅
From Built-in Shadow DOM to the Standard
Until now, we've talked about built-in Shadow DOM. Historically, browsers used it to implement their own elements. Later, this technology was standardized and became available to us, web developers.
The modern Shadow DOM standard is exactly what allows us to create our own components with the same level of encapsulation as built-in <select> or <video>.
There are some differences between the built-in Shadow DOM and the one we will create ourselves. Let's outline them right away to clearly understand the concept of Custom Shadow DOM.
| Criterion | Built-in Shadow DOM | Custom Shadow DOM |
|---|---|---|
| Creation | Created automatically by the browser for built-in elements (<select>, <video>, etc.). |
Created manually by the developer. |
| Access | Closed. Not accessible from outside JavaScript. | Can be either Open or Closed, at the developer's discretion. |
| Styling | Very limited. Styling is only possible through standard CSS properties applied to the element itself (e.g., color, font-size for <select>). |
Fully controlled by the developer. Standard CSS rules are used inside the Shadow DOM. |
| Structure | Defined by the browser, not controlled by the developer, and may vary across different browsers. | Fully defined and controlled by the developer. |
Simply put, we now have a browser technology that allows us to create our own native select. And we can finally decide for ourselves whether to allow styling that damn arrow or not (those who have tried to change the styles of a select will understand)! Sounds great? Let's go!
The Shadow Tree
So, any element can have two sets of child elements:
- Standard (Light DOM): those written in the HTML code.
- Hidden (Shadow DOM): those created programmatically and isolated from the main DOM.
When both trees are present, the browser renders only the Shadow DOM. By the way, it's possible to make desired content from the light tree appear in the shadow tree, but we'll talk about that later in the "Slots" section.
We know how to create light trees; we just didn't know until now that they were called light:
<div class="user-card">
<h3>Hello</h3>
<p>I am a light tree</p>
</div>
In the example above, the user card has a light tree.
Creating a shadow tree requires a bit more effort. There are two approaches: using JavaScript (imperative) and directly in HTML (declarative). This situation can be compared to animation: you can do it simply and quickly using CSS, but with fewer possibilities, or you can use JS for full control.
Let's start with the imperative approach. First, it appeared much earlier, and second, it provides the most complete picture. So, let's create markup with a shadow tree.