Attaching Shadow DOM

el.attachShadow({ mode: 'open' }) gives an element a private subtree: page CSS stays out, inner styles stay in, and host children project through <slot> elements. <template> and <slot> introduced slots and Web Components builds web components. Hosts are custom elements or containers such as div, span and section.

Styles stay inside the shadow rootHTMLLive
<style>p { color: red; margin: 4px 0 }</style>
<p>Page paragraph</p>
<div id="host"><b slot="name">Ada</b></div>
<script>
  const host = document.querySelector('#host');
  const root = host.attachShadow({ mode: 'open' });
  root.innerHTML = `<style>p { color: #1565c0; border: 2px solid; padding: 6px }</style>
    <p>Hello, <slot name="name">stranger</slot>. Page CSS cannot reach me.</p>`;
  root.querySelector('p').append(` shadowRoot found: ${host.shadowRoot === root}`);
</script>
Browser output of Listing 8.29
Browser output of 29

With mode: 'closed', host.shadowRoot is null. Further options: delegatesFocus forwards focus inside, serializable lets getHTML({ serializableShadowRoots: true }) output the root, clonable lets cloneNode() copy it, and slotAssignment: 'manual' enables slot.assign(). Inner events are retargeted to the host; composedPath() shows the origin.