The Shadow DOM: A Quick Explanation

Largely fueled by web components, the shadow DOM seeks to separate content from presentation. It encapsulates HTML and supporting assets (javascript, css, etc.) so components can't be overwritten. This article explores the basics of the Shadow DOM and how you can benefit from it.

Best Example: HTML5 Tags

If you've used HTML5 tags like <video>, then you've also utilized the Shadow DOM. The <video> tag shows only a few lines of code when you inspect it in the DOM tree. So where does all of it's bells and whistles (audio/video controls) get added in?

The answer is the Shadow DOM. The Shadow DOM isn't visible when inspecting the regular DOM tree, yet it dictates the presentation of the <video> tag. How can this be? The inner workings of the tag are actually rendered in a separate document root, aka the Shadow DOM. In this way, the <video> tag is an independent component that we are plugging into our own DOM tree. This serves to hide presentation details that we aren't concerned with for our own development.

Not only does the Shadow DOM hide the <video> tag's HTML markup, it also hides and encapsulates all supporting javascript/css for the <video> element. The Shadow DOM uses HTML imports to serve all assets, which prevents the <video> tag's static files from being overwritten by other css/javascript. In this way, the tag becomes a standalone widget or component.

Utilizing the Shadow DOM

Web components remain only partially supported by major browsers. You can still experiment with the Shadow DOM however. Let's say you have an empty div:

<div id='myDiv'>
</div>

To write to the Shadow DOM, we will first create a shadow root for our div.

<div id='myDiv'>
</div>
<script>
var shadow = document.querySelector('#myDiv').createShadowRoot();
</script>

This creates a shadow root for our div element, meaning our div is now considered a shadow host. The whole idea is that the shadow host renders the content of its shadow root. Lets create a basic <p> tag from the shadow root:

<div id='myDiv'>
</div>
<script>
var shadow = document.querySelector('#myDiv').createShadowRoot();
var p = document.createElement('p');
p.append('hello world');
shadow.appendChild(p);
</script>

In the code above, we create a <p> element. On the last line, we append the element to our shadow root (defined on the first line).

If you inspect this code in your browser, you will notice our <div> element still looks empty. It depends on what browser you're using but you should be able to toggle the Shadow DOM elements so they are visible upon inspection.

Conclusion

The Shadow DOM is still evolving and remains only partially supported today. Despite it's limited functionality, the Shadow DOM will be an integral part of the component based approach to web development. In fact, Angular 2 uses its own version of the Shadow DOM to clearly separate component's content from presentation rendering. By better distinguishing content from presentation and hiding presentation details, the Shadow DOM is something all front end developers should start getting familiar with.

Your thoughts?