The DOM has been a part of our webpages from the beginning, and since the earliest browsers there have always been certain things we wanted, but couldn’t get from the DOM; and other things we wanted to hide.
The shadow DOM is designed exactly for that, it hides DOM subtrees under shadow roots, giving you a method of creating a better and more functional encapsulation in the DOM.
This functionality is very much new and experimental so it’s only available at the moment in Chrome 25+ by enabling Experimental Web Platform features in about://flags, before version 25 it was only available with the webkit prefix.
It is also supported in Opera and the Android Browser using the same prefix.
Firefox will have support for it unprefixed in the next version (as of writing this article).
Browsers have been using the concept of the shadow DOM for a while now, it’s what is used to build widgets like range inputs, video players and most of what comes with HTML5; they are built with HTML and CSS but they are hidden in the Shadow DOM so that you don’t see them, even when inspecting the page.
In the Shadow DOM world, elements on your page get a new node associated with them. This is called the shadow root, you need to create it for your element and this element is called a shadow host.
If you have this node, the content of the shadow host isn’t rendered on the page but the shadow root is rendered instead.
If on your page you had an h1 like this:
This is what you will see on the page and what you will see when you inspect the element, in order to add another node you first need to get the host:
var host = document.querySelector(‘h1’);
Now that you have the host selected, inside a variable you should create the shadow root:
var root = host.createShadowRoot();
Now you can simply change the text context of the h1:
root.textContent = ‘Goodbye’;
If you check this in your browser you can see that what you see on your page is the ‘Goodbye’ and if you try to inspect the element you can see that all you see is the ‘Hello World’ text since the ‘Goodbye’ is hidden from the DOM.
Seeing the Shadow DOM
With a little help from the Chrome Dev Tools you can actually see the Shadow DOM of these elements, to do that:
- Pop open your Developer Tools.
- Go into settings in the top right side of the screen.
- Tick the checkbox near “Show Shadow Dom”.
If you now inspect our h1 element you will see that we can now see a little further into our DOM Tree and actually see where our “Goodbye” Text is written.
We are now able to inspect what we created, and all I did in this part was text, we can also insert entire divs or unordered lists if we want to, let’s say I have this div:
If I want to insert something inside the DOM I have to follow the first two steps above:
var div = document.querySelector(“#outer"); var shadow = div.CreateShadowRoot();
And then when it comes to the third step I should call innerHTML instead of textContent to insert HTML into our element:
shadow.innerHTML = ["We can even create ul's", "
- List Item One ", "
- List Item Two ", "
If you reload the page you can see that it all gets inserted correctly in place.
Using this technique you can even insert styles in the shadow DOM or basically anything you want to separate or even hide from the user.
You can see the demo in here, you can inspect and play with it all you want.
The Shadow DOM has been around and been used by browser makers for quite some time but only now do we get an API that allows us to move around in it, see it and create shadow elements of our own.