Suggest an editImprove this articleRefine the answer for “Shadow DOM vs regular DOM”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**The regular (light) DOM is the document's shared tree, while Shadow DOM is a nested, isolated tree inside a host element with its own styles, markup and behaviour.** The light DOM is reachable by any code through `document.querySelector()` and fully obeys global CSS. Shadow DOM lives inside the host element, is reachable only through `element.shadowRoot`, and global styles never get in; outside content is projected into it with `<slot>`. That is exactly why Web Components and built-in elements such as `<video>` or `<input type="range">` are built on it. ```javascript document.querySelector('my-card').innerHTML; // only the "shell" document.querySelector('my-card').shadowRoot.querySelector('button'); // the inner button ``` **Key point:** the light DOM is shared by the whole page, while Shadow DOM is a separate "mini world" inside an element with its own styles and its own access point.Shown above the full answer for quick recall.Answer (EN)Image**The regular (light) DOM is the document's main tree, while Shadow DOM is a nested, isolated DOM tree inside an element that has its own styles, markup and behaviour and does not affect the outer document.** In plain words: the light DOM is the "surface of the site", and Shadow DOM is the "insides of a component", hidden from the rest of the world. ## Theory ### TL;DR - The light DOM is everything you write in HTML and see in DevTools; Shadow DOM lives inside a host element. - The light DOM obeys global CSS, Shadow DOM is isolated from it. - You reach the light DOM with `document.querySelector()`, and the shadow tree only with `shadowRoot.querySelector()`. - Slots (`<slot>`) exist only in Shadow DOM: they render light DOM content inside the component. - Shadow DOM is what you use for component encapsulation, style isolation and self-contained elements such as `<video>`. ### Quick example ```javascript const card = document.querySelector('.card'); const shadow = card.attachShadow({ mode: 'open' }); shadow.innerHTML = ` <style> button { color: blue; } </style> <button>Inner</button> `; ``` Now `card` has an inner Shadow DOM that is isolated from outside styles, is not part of the ordinary document tree (and with `mode: 'closed'` cannot be reached from outside at all), and manages its own elements. The global rule `button { color: red; }` will not repaint this button, because it lives in its own shadow tree. ### Definitions: light DOM and Shadow DOM | Type | What it is | | --- | --- | | **Regular (light) DOM** | The main tree of the HTML document: everything you write in HTML and see in DevTools. | | **Shadow DOM** | A nested, isolated DOM tree inside an element (a component) that has its own styles, markup and behaviour and does not affect the outer document. | For comparison, an ordinary card in the light DOM: ```html <div class="card"> <h2>Title</h2> <button>Click</button> </div> ``` Everything here is visible in the main DOM, the button can be grabbed with `document.querySelector('button')`, and global styles apply to all of it: `button { color: red; }` makes the button red. ### Key differences | Characteristic | **Regular DOM (light)** | **Shadow DOM** | | --- | --- | --- | | Where it lives | In the document tree | Inside a host element | | Visible in DevTools | Yes | Yes, but hidden by default, enabled by "Show user agent shadow DOM" | | Styling | Obeys global CSS | Isolated from global styles | | Isolation | None, styles and JS affect each other | Full, an isolated context | | Used in | Any HTML | Web Components, built-in elements (`<video>`, `<input>` and others) | | Interaction | Directly via `document.querySelector()` | Only via `shadowRoot.querySelector()` | | Slots | No | Yes (`<slot>` projects content from the light DOM) | ### Structure and slots ```html <body> <my-card> <!-- the host element --> #shadow-root (shadow DOM) <style>...</style> <button>Click</button> #light-dom (regular DOM) <p slot="content">...</p> </my-card> </body> ``` Here `my-card` is the host element, `#shadow-root` is its inner Shadow DOM, and outside elements can pass content in through `<slot>`. Note that the slotted `<p>` physically stays in the light DOM and is still subject to global styles, it is merely rendered at a chosen place in the shadow tree. ### Access from code From the light DOM you only see the component's "shell": ```javascript console.log(document.querySelector('my-card').innerHTML); // Empty, because the insides are hidden in the Shadow DOM ``` The shadow tree is reachable only through a reference to its root: ```javascript const shadow = document.querySelector('my-card').shadowRoot; console.log(shadow.querySelector('button')); // <button>Click</button> ``` If the tree was created with `mode: 'closed'`, `shadowRoot` is `null` and the inner nodes cannot be reached from outside at all. ### Where you actually need it Reach for Shadow DOM when you need to: - encapsulate a component (web components, UI libraries); - isolate styles so global CSS cannot break the look; - build a reusable element, for example `<custom-slider>`; - make a component self-contained, like `<video>` or `<select>`. A real-life example. In the regular DOM you redefined button styles across the whole site, and suddenly the buttons inside a component "broke", because the styles are global. With Shadow DOM, a component with its own styles is isolated, and no global `button { color: red }` touches it. | Criterion | **Regular DOM** | **Shadow DOM** | | --- | --- | --- | | Visibility | Available to all code | Hidden and isolated | | Styles | Shared | Isolated | | Usage | Everyday HTML | Components and built-in elements | | Interaction | Through `document` | Through `shadowRoot` | | Safety | No isolation | Encapsulated | ### Common mistakes - Looking for a component's inner nodes with `document.querySelector()`: the selector does not cross the shadow boundary. - Assuming global CSS will "just work" inside a component: styles get in through the component's own `<style>`, CSS custom properties or `::part`. - Confusing a slot with moving the node: slotted content stays in the light DOM, it is not copied into the shadow tree. - Treating `closed` as data protection: it only makes access harder, it provides no real security. - Forgetting about events: to make an event from the shadow tree bubble out you create it with `composed: true`, and from the outside its `target` will be the host.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.