17

Reading through articles and tutorials about the Shadow DOM, I came across a description which confused me a bit:

"Shadow DOM refers to the ability of the browser to include a subtree of DOM elements into the rendering of a document, but not into the main document DOM tree."

So a Shadow tree is not part of the DOM tree? But the browser will still see it and render its contents?

TylerH
  • 20,799
  • 66
  • 75
  • 101
Daver Muzaffar
  • 648
  • 1
  • 7
  • 17
  • 1
    The idea is that the tree that the browser is rendering is hidden behind custom elements. A good example is the video tag, many of the controls could be implemented with divs and buttons but you as the user, you do not have access to those internals. The internal representation is not available to code outside the custom component unless you expose it through the shadow DOM or custom methods. See http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom/ – Ruan Mendes Apr 15 '16 at 22:10
  • Yes the shadow DOM is not really part of the tree, from the point of code l view of the caller, it's hidden behind the implementation and that's the whole point – Ruan Mendes Apr 15 '16 at 22:14

3 Answers3

19

I think the easiest way to understand shadow DOM is by example:

<div>
  <input type="range">
</div>

Your DOM for the above code will look exactly as you'd probably expect it:

div
- input[type=range]

But what your browser renders is something else: There's a horizontal line and a thumb (or knob or whatever you call it). So internally, the input has some child elements, but they are not exposed through the DOM:

div
- input[range]
  - bar
  - thumb

But as I already wrote: Those are not exposed through the DOM, so they are hidden to you, your CSS, your JS (this is not entirely true, browsers can give you some access, for example Webkit-based browsers allow you to manipulate the appearance of the thumb in CSS via the -webkit-slider-thumb pseudo element).

On the other hand, these elements need to be in the DOM somewhere to be rendered by the browser, and that's where shadow DOM comes in: Internally, the browser replaces every ocurence of input[type=range] in the DOM by the tree

input[range]
- bar
- thumb

And that is shadow DOM: Some elements that are children of certain elements, not because you put them there in your HTML, but because the parent element is defined to have these children (like the audio-element is defined to have a play-button) and that are not exposed through the DOM, but are generated by the browser internally.

A lot more examples and a more thorough explanation can be found here: What the Heck is Shadow DOM?

mmgross
  • 3,064
  • 1
  • 23
  • 32
8

From the Shadow DOM spec,

A document tree is a node tree whose root node is a document.

Any element can host zero or one associated node trees, called a shadow tree.

A shadow host is an element that hosts one shadow tree.

A shadow root is the root node of a shadow tree.

A tree of trees is a tree of node trees.

enter image description here

Then, yes, shadow trees are outside the document tree, but they are still linked forming a tree of trees.

And yes, the shadow contents are rendered instead of the descendants of the element, as defined in CSS Scoping:

The most recently-created shadow tree on an element is the active shadow tree for that element.

The descendants of a shadow host must not generate boxes in the formatting tree. Instead, the contents of the active shadow tree generate boxes as if they were the contents of the element instead.

Oriol
  • 274,082
  • 63
  • 437
  • 513
-1

It looks like the quote came from this article titled: What the Heck is Shadow DOM?

The shadow DOM is part of the DOM (but a virtual DOM is a hidden copy of the DOM. Sorry about the earlier confusion with virtual DOM!). From reviewing this W3 Spec again, it appears that the shadow DOM is simply a reusable DOM fragment. The browser will see it & will render it's contents.

This specification describes a method of combining multiple DOM trees into one hierarchy and how these trees interact with each other within a document, thus enabling better composition of the DOM.

This technology has been around since at least 2006, when I started using .innerHTML & templates inside of JavaScript, to build reusable DOM fragments. It's not new technology. It's simply being documented in 2015 by the W3C as an official specification.

What is interesting are these CSS attributes & pseudo-selectors, which operate on the Shadow DOM, but aren't part of the Real DOM. They are described at the bottom of the Composed Trees section of the W3 Spec.

::shadow pseudo element

/deep/ combinator, which was replaced with a >>> combinator (or shadow piercing descendant combinator)

::content pseudo-element

:host pseudo-class and :host() functional pseudo-class

:host-context() functional pseudo-class

They kind of add to these selectors, which people sometimes use to create <div> tags with carets/pointers to other on-screen elements:

::before & ::after

Additional Update:

I found more details at Shadow DOM 101 link. When viewing the "Hello my name is Bob... Shellie" example (about 1/2 way down the page), which is right above this text block...

Now we have achieved separation of content and presentation. The content is in the document; the presentation is in the Shadow DOM. They are automatically kept in sync by the browser when it comes time to render something.

... we can inspect the DOM & see what the shadow DOM looks like. It looks like this, where both CSS & HTML can be encapsulated inside of a "shadow DOM" element, which is hidden inside of a <div> tag. See: https://developer.chrome.com/devtools/docs/settings-files/show-shadow-dom.png

It seems like the idea is to encapsulate the CSS & HTML, so that it doesn't spill out onto other areas of the page. Nor allow other existing / on-page code, to affect what is inside of that encapsulated code block. Older examples of this encapsulation would be hidden <iframe> tag, which were designed to show ads but stop 3rd party ad code from breaking the JS on our really cool web pages.

Here are some more Shadow DOM links:

  1. Shadow DOM 101
  2. Shadow DOM 201
  3. Shadow DOM 301
  4. Visualizing Shadow DOM Concepts
Clomp
  • 3,168
  • 2
  • 23
  • 36
  • 1
    Oh boy, I'm even more confused now. The shadow dom is different than the virtual dom right? I was referring to the shadow dom thats part of Web Components: http://www.w3.org/TR/2015/WD-shadow-dom-20151215/ – Daver Muzaffar Apr 15 '16 at 21:52
  • The shadow dom is the virtual dom. There are only 2: "visible" DOM & "hidden" DOM. The browser only renders the visible DOM (which we normally see), but not the hidden DOM. The terms are interchangeable & can be confusing. Real = viewable = visible. Shadow = virtual = hidden. Does that help? Or do I need to edit my answer to make it clearer? – Clomp Apr 15 '16 at 22:01
  • I don't know ReactJS, but its "virtual DOM" seems something completely different than shadow DOM. – Oriol Apr 15 '16 at 22:04
  • I think you will confuse people even more, shadow DOM and react are not exactly the same thing. There are similarities, but you haven't presented them clearly – Ruan Mendes Apr 15 '16 at 22:04
  • I was under the same impression, that the virtual DOM and shadow DOM and different. I am familiar with Reactjs and the virtual DOM. But I thought the shadow DOM is separate from the virtual DOM. The shadow DOM is something thats for encapsulation purposes. I am new to all this, so good chance I'm wrong. – Daver Muzaffar Apr 15 '16 at 22:08
  • Yeah, did some looking around..it seems the virtual DOM and shadow DOM are not at all the same thing. – Daver Muzaffar Apr 15 '16 at 22:10
  • Oh right, they are separate. We're throwing around the terminology at work as if they are the same thing. Shadow DOM = DOM fragments, which can be reused, but they aren't the Virtual DOM. We're mixing reusable React JS components & nesting them together like DOM fragments. I'll update my answer in a bit. Here is the actual Shadow DOM spec, with more illustrations: https://www.w3.org/TR/2015/WD-shadow-dom-20151215/#shadow-dom-example – Clomp Apr 15 '16 at 22:37
  • Thanks for updating, I really do appreciate the help. – Daver Muzaffar Apr 15 '16 at 23:28
  • You're welcome! I've added some more documentation & links. The image example shows how the shadow DOM encapsulates/hides the CSS & HTML, so that other people's code can't touch that web component's code & vice versa. – Clomp Apr 15 '16 at 23:43
  • Awesome, I had not come across the last link you provided. I found that one very helpful. Thanks again – Daver Muzaffar Apr 16 '16 at 00:07
  • You're welcome! Sometimes trying to explain it helps to mentally clarify what the concepts are. I had originally started researching shadow DOM right before learning about React's virtual DOM. So they quickly became intertwined in my mind as the same thing. Explaining this helped me separate those two concepts & see how the controls in sliders, video players & audio components are separate & distinct from the virtual DOM, plus how CSS & HTML elements can be protected in a shadow DOM without having to use ` – Clomp Apr 16 '16 at 00:39
  • I was confused about the two also. I learned React and the virtual DOM first and then the shadow DOM. It's an interesting concept (shadow DOM), lets see how popular its usage becomes in the future. – Daver Muzaffar Apr 16 '16 at 05:25