Shadow DOM

A private DOM subtree whose markup and selectors stay behind a component boundary, protecting a widget from most page CSS and vice versa.

styles that stay inside the componentstop the host page CSS from wrecking my widgethidden DOM inside an elementmy Tailwind classes do nothing inside this elementCSS not leaking in or outthe #shadow-root line I see in DevToolsshaddow DOMwhy can't my querySelector reach inside this element

See it

Live demo coming soon

What it is

Shadow DOM attaches an encapsulated DOM subtree to a host element with attachShadow(). Ordinary selectors outside cannot reach its internal markup, and its internal styles do not select the surrounding page. Slots can project light-DOM children into that subtree, which is why Shadow DOM is a core piece of the Web Components toolkit. The browser already uses it on you: the play button and scrubber inside a video element live in a user-agent shadow tree.

Reach for it when an embeddable widget or design-system element must survive unknown page CSS without leaking its own selectors back out. Expose deliberate styling hooks with CSS custom properties and ::part instead of making consumers depend on private internal markup.

Gotcha: the boundary is not a security wall. Inherited properties and CSS custom properties can cross it, events may be retargeted at the host, and mode: 'closed' only hides shadowRoot from ordinary access. Global resets also stop at the boundary, so the component must supply its own complete base styles.

Ask AI for it

Build a <user-card> element that calls attachShadow({ mode: 'open' }) once and renders its private markup and styles inside the shadow root. Add a named <slot> for caller-supplied actions, expose the avatar with part='avatar' so consumers can style it through ::part(avatar), and accept --user-card-accent as a CSS custom property with a safe fallback. Do not expose internal class names as public API, and add a click test that verifies event.target is retargeted at the host outside the shadow root.

You might have meant

componentprogressive enhancementslot children patterncss in js vs css modulesutility first css

Go deeper