What is the Shadow DOM?
Answer
Shadow DOM is a web standard that provides encapsulation for DOM and CSS. It allows you to attach a hidden, separate DOM tree to an element, keeping its internal structure and styles isolated from the main document.
DOM Structure
Creating Shadow DOM
// Get the host element
const host = document.querySelector("#my-component");
// Attach shadow root
const shadow = host.attachShadow({ mode: "open" });
// Add content to shadow DOM
shadow.innerHTML = `
<style>
/* These styles are scoped! */
p { color: blue; font-size: 20px; }
.internal { background: yellow; }
</style>
<div class="internal">
<p>This is inside Shadow DOM</p>
</div>
`;
Mode: Open vs Closed
// Open mode - shadow root accessible via JavaScript
const openShadow = element.attachShadow({ mode: "open" });
console.log(element.shadowRoot); // Returns shadow root
// Closed mode - shadow root not accessible
const closedShadow = element.attachShadow({ mode: "closed" });
console.log(element.shadowRoot); // Returns null
CSS Encapsulation
<!-- Main document -->
<style>
p {
color: red;
} /* Won't affect shadow DOM */
.internal {
background: green;
} /* Won't affect shadow DOM */
</style>
<div id="my-component">
<!-- Shadow DOM content is protected -->
</div>
<p>This is red (main document)</p>
// Inside shadow DOM
shadow.innerHTML = `
<style>
p { color: blue; } /* Only affects this shadow DOM */
</style>
<p>This is blue (shadow DOM)</p>
`;
Slots - Content Projection
// Component with slot
shadow.innerHTML = `
<style>
.wrapper { border: 2px solid blue; padding: 10px; }
</style>
<div class="wrapper">
<slot></slot> <!-- Content goes here -->
</div>
`;
<!-- Usage -->
<my-component>
<p>This content goes into the slot!</p>
</my-component>
Named Slots
shadow.innerHTML = `
<header>
<slot name="title"></slot>
</header>
<main>
<slot></slot> <!-- Default slot -->
</main>
<footer>
<slot name="footer"></slot>
</footer>
`;
<my-component>
<h1 slot="title">Card Title</h1>
<p>Main content (default slot)</p>
<span slot="footer">Footer text</span>
</my-component>
Real-World Examples
Shadow DOM is used in native HTML elements:
<!-- These use Shadow DOM internally -->
<video controls></video>
<input type="range" />
<input type="date" />
<details>
<summary>Click</summary>
Content
</details>
Browser DevTools
To inspect Shadow DOM:
- Open DevTools → Elements
- Click ⚙️ Settings → Show user agent shadow DOM
- Expand
#shadow-rootin the element tree
Key Points
- Encapsulation: Styles and DOM are isolated
- Scoped CSS: No style leaking in or out
- Slots: Allow content projection
- Native support: Used by browser UI elements
- Web Components: Foundation for custom elements