Daver Muzaffar
Daver Muzaffar

Reputation: 708

Need help understanding the Shadow DOM

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?

Upvotes: 20

Views: 4444

Answers (3)

Clomp
Clomp

Reputation: 3308

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

Upvotes: 0

mmgross
mmgross

Reputation: 3092

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?

Upvotes: 20

Oriol
Oriol

Reputation: 288600

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.

Upvotes: 8

Related Questions