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.
See it
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.