Building Your Learning Module...
Getting things ready for you!
Find videos you like?
Save to resource drawer for future reference!
Shadow DOM is a web standard that provides encapsulation for DOM and CSS. It allows you to attach a hidden DOM tree to an element, completely isolated from the main document. Styles defined inside Shadow DOM don't leak out, and styles from the page don't leak in.
Styles and markup are completely isolated
Shadow DOM tree is hidden from main document
Use slots to insert content from Light DOM
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Shadow DOM Basics</title>
</head>
<body>
<div class="container">
<h1>🛡️ Shadow DOM Protection</h1>
<div class="demo-section">
<h3>1️⃣ Regular DOM (No Protection)</h3>
<div class="warning">
This div gets affected by global .warning styles!
</div>
</div>
<div class="demo-section">
<h3>2️⃣ Shadow DOM (Protected)</h3>
<div id="shadow-host"></div>
</div>
<div style="margin-top: 30px; padding: 20px; background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%); border-radius: 12px; border-left: 4px solid #f59e0b;">
<strong style="color: #92400e; display: block; margin-bottom: 8px;">💡 Notice the Difference:</strong>
<p style="color: #78350f; font-size: 14px; line-height: 1.6;">
The first div gets affected by global .warning styles, but the Shadow DOM version is completely isolated!
</p>
</div>
</div>
</body>
</html>Loading preview...
attachShadow()<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Shadow DOM with Slots</title>
</head>
<body>
<div class="container">
<h1>🎰 Slots: Content Projection</h1>
<!-- Custom element with slotted content -->
<user-card>
<span slot="name">Sarah Johnson</span>
<span slot="role">Senior Developer</span>
<p slot="bio">
Passionate about building scalable web applications.
Love working with modern JavaScript and Web Components!
</p>
<img slot="avatar" src="https://i.pravatar.cc/150?img=5" alt="Sarah">
</user-card>
<user-card>
<span slot="name">Michael Chen</span>
<span slot="role">UI/UX Designer</span>
<p slot="bio">
Creating beautiful and intuitive user experiences.
Advocate for accessible design and user-centered thinking.
</p>
<img slot="avatar" src="https://i.pravatar.cc/150?img=12" alt="Michael">
</user-card>
</div>
</body>
</html>Loading preview...
slot="name" attribute<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Open vs Closed Shadow DOM</title>
</head>
<body>
<div class="container">
<h1>🔓 vs 🔒 Shadow DOM Modes</h1>
<div class="grid">
<!-- Open Mode -->
<div class="demo-card open-mode">
<h2>🔓 mode: 'open'</h2>
<p style="color: #6b7280; margin-bottom: 16px;">
Shadow root is accessible via JavaScript
</p>
<div id="open-host"></div>
<button class="open-btn" onclick="accessOpen()">
Try to Access Shadow Root
</button>
<div id="open-result" class="result"></div>
</div>
<!-- Closed Mode -->
<div class="demo-card closed-mode">
<h2>🔒 mode: 'closed'</h2>
<p style="color: #6b7280; margin-bottom: 16px;">
Shadow root is NOT accessible
</p>
<div id="closed-host"></div>
<button class="closed-btn" onclick="accessClosed()">
Try to Access Shadow Root
</button>
<div id="closed-result" class="result"></div>
</div>
</div>
<div style="background: white; padding: 30px; border-radius: 16px; box-shadow: 0 8px 32px rgba(0,0,0,0.2);">
<h2 style="color: #667eea; margin-bottom: 16px;">📚 Key Differences</h2>
<div style="display: grid; gap: 16px; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));">
<div style="padding: 16px; background: #f0fdf4; border-radius: 8px; border-left: 4px solid #10b981;">
<strong style="color: #065f46; display: block; margin-bottom: 8px;">Open Mode</strong>
<ul style="color: #047857; font-size: 14px; line-height: 1.8; padding-left: 20px;">
<li>shadowRoot is accessible</li>
<li>Can query shadow DOM from outside</li>
<li>Useful for debugging</li>
<li>More flexible</li>
</ul>
</div>
<div style="padding: 16px; background: #fef2f2; border-radius: 8px; border-left: 4px solid #ef4444;">
<strong style="color: #991b1b; display: block; margin-bottom: 8px;">Closed Mode</strong>
<ul style="color: #b91c1c; font-size: 14px; line-height: 1.8; padding-left: 20px;">
<li>shadowRoot returns null</li>
<li>Cannot access from outside</li>
<li>Better encapsulation</li>
<li>More secure</li>
</ul>
</div>
</div>
</div>
</div>
</body>
</html>Loading preview...
Selects the shadow host element
:host {
display: block;
padding: 1rem;
}
:host(.active) {
background: blue;
}Styles slotted content
::slotted(*) {
font-family: inherit;
}
::slotted(p) {
color: blue;
}Match host with ancestor selector
:host-context(.dark) {
background: #000;
color: #fff;
}Style shadow parts from outside
/* In Shadow DOM */
<div part="button">Click</div>
/* From outside */
my-element::part(button) {
color: red;
}