light, shadow, flattened DOM

Shadow DOM

Shadow DOM, if exists, is rendered instead of light DOM.

let root = host.attachShadow({mode: 'open'});

// ⭐️ shadow DOM
root.innerHTML = `
  <style> p { font-weight: bold; } </style>
  <p>Hello, John!</p>
`;

Light DOM

The markup a user of your component writes. This DOM lives outside the component's shadow DOM. It is the element's actual children.

<better-button>
  <!-- ⭐️ light DOM -->
  <img src="gear.svg" slot="icon">
  <span>Settings</span>
</better-button>

If we’d like to track internal modifications of light DOM from JavaScript, use: MutationObserver.

Flattened DOM

The result of the browser distributing the user's light DOM into your shadow DOM, rendering the final product. The flattened tree is what you ultimately see in the DevTools and what's rendered on the page.

the flattened DOM exists only for rendering and event-handling purposes. It’s kind of “virtual”. That’s how things are shown. But the nodes in the document are actually not moved around❗️

The process of rendering slotted elements inside their slots is called “composition”.

<user-card>
  #shadow-root
    <div>Name:
      <slot name="username">
        <!-- ⭐️ slotted element is inserted into the slot -->
        <span slot="username">John Smith</span>
      </slot>
    </div>
    <div>Birthday:
      <slot name="birthday">
        <span slot="birthday">01.01.2001</span>
      </slot>
    </div>
</user-card>

Last updated