Shadow Root Modes — Complete Guide
DodaTech
Updated 2026-06-28
2 min read
In this tutorial, you will learn about Shadow Root Modes. We cover key concepts, practical examples, and best practices to help you master this topic.
Shadow root modes (open vs closed) control external access to the shadow tree, with open mode allowing element.shadowRoot and closed mode returning null.
What You'll Learn
- The difference between open and closed shadow modes
- When to use each mode
- How closed mode affects Accessibility and testing
- Why closed mode is not a security feature
Why It Matters
Choosing the right mode affects how other developers interact with your component. Open is almost always the right choice.
flowchart LR
A[attachShadow] --> B{mode}
B -->|open| C[shadowRoot accessible]
B -->|closed| D[shadowRoot = null]
C --> E[Testing, debugging]
C --> F[Accessibility tools]
D --> G[Hides internals]
Open Mode
const openHost = document.querySelector('#open-host');
const openShadow = openHost.attachShadow({ mode: 'open' });
openShadow.innerHTML = '<p>Accessible shadow content</p>';
console.log('Open shadow root:', openHost.shadowRoot); // Returns the shadow root
console.log('Mode:', openShadow.mode); // 'open'
// External code can query, modify, and traverse
const paragraph = openHost.shadowRoot.querySelector('p');
console.log('Paragraph text:', paragraph.textContent);
Closed Mode
const closedHost = document.querySelector('#closed-host');
const closedShadow = closedHost.attachShadow({ mode: 'closed' });
closedShadow.innerHTML = '<p>Inaccessible shadow content</p>';
console.log('Closed shadow root:', closedHost.shadowRoot); // null!
// The shadow reference is only available inside the component
// External code cannot access closedShadow unless it was captured
// closedShadow.querySelector('p') works here because we have the reference
console.log('Paragraph text:', closedShadow.querySelector('p').textContent);
Why Open Mode is Preferred
class AccessibleComponent extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' }); // Always open
}
// Open mode allows:
// 1. Testing: element.shadowRoot.querySelector
// 2. Debugging: DevTools Elements panel
// 3. Accessibility: screen readers can traverse
// 4. Styling: ::part() requires open mode
}
customElements.define('accessible-comp', AccessibleComponent);
Common Mistakes
- Using closed mode thinking it provides security (it can be bypassed)
- Using closed mode for components that should be testable
- Attaching a second shadow root to an element with closed mode
Practice Questions
- What does openHost.shadowRoot return for a closed shadow root? null.
- Why is open mode preferred? Testing, debugging, accessibility, and CSS parts support.
Mini Project
Create two identical components, one with open mode and one with closed mode. Demonstrate the difference in DevTools and console access.
What's Next
Lesson 3: Attaching Shadow DOM
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro