Middle
What is Shadow DOM?
sobes.tech AI
Answer from AI
Shadow DOM is a web standard that allows encapsulating HTML, CSS, and JavaScript into separate, isolated blocks from the main document.
Main concepts:
- Shadow Host: A DOM element to which Shadow DOM is attached.
- Shadow Tree: An isolated subtree of the DOM.
- Shadow Boundary: The boundary between Shadow DOM and the main document.
- Shadow Root: The root node of the Shadow Tree. Created using
element.attachShadow({ mode: 'open' | 'closed' }):open: Shadow Root is accessible from outside viaelement.shadowRoot.closed: Shadow Root is not accessible from outside.
Advantages:
- Style encapsulation: Styles defined within Shadow DOM do not leak out and do not affect the main document. Styles from the main document do not affect Shadow DOM by default, but this can be controlled.
- DOM encapsulation: Elements inside Shadow DOM are not visible in the main DOM tree, preventing accidental selector crossing and manipulations.
- Behavior encapsulation: Logic and event handlers can be isolated within Shadow DOM.
Example of creating Shadow DOM:
// Create a new DIV element
const hostElement = document.createElement('div');
// Attach Shadow DOM to the element
const shadowRoot = hostElement.attachShadow({ mode: 'open' });
// Add content to Shadow DOM
shadowRoot.innerHTML = `
<style>
/* Style applicable only inside this Shadow DOM */
p {
color: blue;
}
</style>
<p>This is text inside Shadow DOM</p>
`;
// Append host element to the main document
document.body.appendChild(hostElement);
Applications:
- Creating reusable web components.
- Isolating styles of third-party libraries.
- Protecting internal component details from external interference.
Features of working with styles:
- External styles do not affect Shadow DOM by default.
- You can use the
:hostpseudo-class to style the Shadow Host from inside Shadow DOM. - You can use
:host-context()to style based on the context of the Shadow Host. - You can use the
::slotted()pseudo-element to style elements placed in slots (<slot>).
<my-component>
<!-- This element will be "sent" into the slot inside Shadow DOM -->
<span>Slot content</span>
</my-component>
// Inside the Shadow DOM of the my-component
const shadowRoot = this.attachShadow({ mode: 'open' });
shadowRoot.innerHTML = `
<style>
/* Style for an element placed in a slot named "my-slot" */
::slotted(span) {
font-weight: bold;
}
</style>
<div>Main content of the component</div>
<slot></slot> <!-- Slot content will be displayed here -->
`;
Shadow DOM is part of the Web Components specification.