Shadow DOM

Posted by

Shadow DOM encapsulates a component inside a new hidden DOM tree. Shadow DOM allows to attach the hidden DOM tree to any node in the main document. The purpose of Shadow DOM encapsulation is to prevent the “component styles” from affecting non-shadow nodes.

A native example of Shadow DOM encapsulation is <video>, which encapsulates video controls inside the shadow DOM.

Shadow Host

The regular DOM node that the shadow DOM is attached to.

Shadow tree

The DOM tree inside the shadow DOM.

Shadow boundary

the place where the shadow DOM ends, and the regular DOM begins.

Shadow root (= Shadow Host)

The root node of the shadow tree.

Basic usage

Attach a shadow root to any element using the Element.attachShadow() method. This takes as its parameter an options object that contains one option – mode – with a value of open or closed.

let shadow = elementRef.attachShadow({mode: 'open'});
let shadow = elementRef.attachShadow({mode: 'closed'});

open

you can access the shadow DOM using JavaScript written in the main page context, for example using the Element.shadowRoot property.

close

If you attach a shadow root to a custom element with mode: closed set, you won’t be able to access the shadow DOM from the outside — myCustomElem.shadowRoot returns null. This is the case with built in elements that contain shadow DOMs, such as <video>.

Create a Shadow DOM

To create a Shadow DOM, define a class which extends HTMLElement.

class PopUpInfo extends HTMLElement {
  constructor() {
    // Always call super first in constructor
    super();

    // write element functionality in here

    ...
  }
}

Use DOM manipulation such as createElement(), setAttribute() and appendChild(). Then, append the component to the shadow root by attachShadow().

Styling a Shadow DOM

// Create some CSS to apply to the shadow dom
let style = document.createElement('style');

style.textContent = `
	.class {
		color: red;
	}
`;

// attach the created elements to the shadow dom
shadow.appendChild(style);
shadow.appendChild(wrapperElement);

Use the custom element

Define a custom element with the class so that the shadow DOM is available.

// Define the new element
customElements.define('popup-info', PopUpInfo);

Thanks for reading.

Hope you enjoyed the article. If you have any question or opinion to share, feel free to write some comments.

References

Facebook Comments