When you think about creating a web page, we typically think about the HTML elements we structure and style and interactive with using CSS and JS. For the sake of simplicity, we will call the elements you see rendered as the Light DOM.
The Shadow DOM by contrast is a way to create elements that are not affected by the same attributes and properties as those in the Light DOM. The Shadow DOM provides true scope encapsulation; your element’s CSS and JS are scoped to it alone! Think of the Shadow DOM as a lightweight version of an iframe.
To render elements created via the Shadow DOM, you must ‘inject’ them into the Light DOM. We’ll cover some examples of this later in the post.
The most common example is the Video Tag. Take this simple example tag:
<video src="Clipped_Red_Lexus.mov" controls></video>
This simple tag results in the following rendered HTML in your browser:
Notice how much “extra” HTML is rendered under the “#shadow-root”. This code is generated by your browser automatically to give you these complex UI elements like the Play Button and the Volume Slider.
These elements have their own styling and event listeners that are not affected by the host DOM.
Using the Shadow DOM you can create truly re-usable pieces of code you know will act reliably no matter where you place them. Create one widget, and use it in any of your code, and stop worry about CSS and JS collisions!
Also, most importantly, the Shadow DOM is the base from which the modern web is being built upon.
Clearly, understanding this is quite important to understanding these new web frameworks.
Here is a very basic example illustrating using the Shadow DOM to inject elements into a host root.
Here is a very basic example showing the isolated CSS styling when using the Shadow DOM.
Please note the injected element’s CSS does not affect the CSS in the host element. Only the injected elements are red.
Here is an example showing insertion points and querying using the content tag. (Please note, that in Shadow DOM v1, the content tag will be replaced by the slot selector, read more about this below in “Whats Next”)
This simple example shows how one can select some content from the host element, inject it into the Shadow DOM template, which in turn get injected into the host DOM.
We reviewed some concepts about the Shadow DOM laid out in what is commonly referred to as “Shadow DOM v0”. This is to say we are working with the very first iteration of the implementation.
The new spec for v1 has, for the most part, been agreed upon and the major browser publishers are working on implementing the new features.
Hayato Ito at Google has a great list explaining some of the changes we can expect along with simple examples showing these new features.
While I provided only simple examples of the Shadow DOM, I hope this inspires you to explore more yourself. Thanks for reading!