# light, shadow, flattened DOM

{% tabs %}
{% tab title="📗 參考" %}
* [ ] :floppy\_disk: [`<show-hello>`](https://replit.com/@pegasusroe/lessshow-hellogreater#script.js) -  hides its internal DOM in shadow tree
* [ ] JS.info ⟩ [Shadow DOM](https://javascript.info/shadow-dom)
{% endtab %}

{% tab title="👉 相關" %}
* [flattened DOM](../slots#flattened-dom)
* [Using Slots](slots)
{% endtab %}
{% endtabs %}

## Shadow DOM

{% hint style="info" %}
**Shadow DOM**, if exists, is **rendered** instead of **light DOM**.
{% endhint %}

```javascript
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.

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

{% hint style="info" %}
If we’d like to **track** internal **modifications** of **light DOM** from JavaScript, use: [MutationObserver](https://javascript.info/mutation-observer).
{% endhint %}

## 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.

{% hint style="warning" %}
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](../slots#slotted-elements) inside their **slots** is called “**composition**”.
{% endhint %}

```markup
<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>
```
