Lesson 36 of 55 · HTML
Web Components – Shadow DOM
Duration: 10 min
Shadow DOM Basics
The Shadow DOM creates a private subtree for a component, isolating its CSS and markup from the main document.
class Card extends HTMLElement {
constructor() {
super();
const shadow = this.attachShadow({ mode: 'open' });
shadow.innerHTML = `
<style>
:host { display: block; border: 1px solid #ccc; padding: 1rem; }
h2 { margin: 0; color: teal; }
</style>
<h2><slot name='title'></slot></h2>
<div><slot></slot></div>
`;
}
}
customElements.define('my-card', Card);
<my-card>
<span slot='title'>Hello</span>
This is the card content.
</my-card>
Styling hooks
:host– Styles the custom element itself from inside the shadow tree.::slotted(selector)– Styles content projected into a<slot>.::part(name)– Exposes internal parts for external styling.::theme– Future proposal for theming custom elements.
Benefits
- Encapsulation – Prevents style leakage and name collisions.
- Predictable styling – The component looks the same regardless of page CSS.
- Scoping – Allows you to ship a component with its own stylesheet without polluting the global scope.
Quick checklist for Shadow DOM
- Shadow root attached (
attachShadow) withopenorclosedmode? ✅ - Use of
:hostand::slottedselectors for styling? ✅ - Slots defined for content projection? ✅
::partused where external styling is needed? ✅- No unintended global CSS affecting the component? ✅
Tip: Use
:host-context()to style a component based on its surrounding context (e.g., dark‑mode detection).