DOM
Before we dive into shadow DOM, let's rewind what a DOM is. According to the definition, the DOM is a Programming Interface that allows the interaction with the structure, style, and content of a web page. The DOM parser parses the HTML/XML Document and creates a tree-like structure where each element in the tree is called a node. Likewise, the CSSOM parser parses the stylesheets/inline styles and creates a tree-like structure similar to DOM where-in each node contains the required style information. Finally, the outputs of DOM and CSSOM parsers are combined together, and the render tree is built which beautifully displays the content in the webpage.
Shadow DOM
Shadow DOM is an *encapsulated DOM * that is rendered separately from the main document. The script and styling present in the shadow DOM are private to the shadow DOM. This means that document.querySelector()
will not return the Shadow DOM elements. The styles added to the shadow DOM will not leak outside of the Shadow DOM and the outside styles will not leak inside the shadow DOM. Therefore, you can apply styles directly to the generic selectors, ids, and classes without worrying about the conflicts. Shadow DOM provides both DOM and Style encapsulation.
Shadow DOM vs Virtual DOM
A few frameworks such as React.js, Vue.js make use of Virtual DOM to optimize the performance. React.js creates a copy of the real DOM and saves it in the memory. This copied version is called Virtual DOM. React.js doesn't update the real DOM directly. It runs a diffing algorithm to find out the changes. Whenever the state changes, React.js compares Virtual DOM with its previous versions. If it finds any, it updates only those changes into the real DOM. This process is called Reconciliation. So, the virtual DOM is used for improving performance and the Shadow DOM is used for encapsulation. You can create virtual DOM and attach it to shadow DOM or vice versa.
Are Web components and shadow DOM the same?
No. Shadow DOM is the technology used in Web components. Web components are developed on top of shadow DOM. They make use of encapsulation provided by shadow DOM. They provide the set of APIs using which we can create encapsulated, reusable, custom elements. These components are framework agnostic that can be used across all javascript applications.
Difference between web components and components created by Vue.js, React, Angular
DOM encapsulation:
As I said earlier, the difference lies in the encapsulation part. Although the frameworks support component reusability, a component will still have access to elements in other components using query selector APIs (document.querySelector()
). In the case of Web components, each component is strongly encapsulated and can only be accessed within the shadow DOM.document.querySelector()
does not return the elements on other web components.Style encapsulation:
The frameworks like Vue.js and React.js don't support style encapsulation natively. For vue.js,vue-loader
supportsscoped
attribute for style tags. Other frameworks make use of css modules, css-in-js libraries to handle style encapsulation. However,Angular
supports emulated style encapsulation. It provides an option called encapsulation in the component API.
Building blocks of shadow DOM
-
Shadow host - The shadow host is the same as the other child nodes attached to the real DOM. It can be div, span, or anything in this list.
<text-area>
,<input />
have their own shadow DOM built-in by the browser. - Shadow tree - The DOM tree inside the shadow DOM
- Shadow root - The root node of the Shadow tree
Shadow DOM looks like below,
HTML Structure
Creating Shadow DOM
const shadowHost = document.createElement('div');
const shadowRoot = shadowHost.attachShadow({mode: 'open'});
shadowHost.id = 'shadow-host';
shadowRoot.innerHTML = `
<h1>Hi, there!/h1>
<style>
h1 {
color: green;
}
</style>`;
Hence, any element that calls attachShadow
will become a shadow host and create a shadow tree.
In the above code, the mode is set to open
. If the shadow root is created with open
mode, the shadow root can be accessed by the real DOM elements in the following way,
document.querySelector('#shadow-host').shadowRoot.innerHTML
If the mode is set to closed
, the above code will return null
.
Browser compatibility
Shadow DOM is supported by the latest browsers such as Chrome, Firefox (63 and onwards), Opera, Safari, and Edge. The polyfills are also available for the unsupporting browsers.
Top comments (0)