> For the complete documentation index, see [llms.txt](https://wplake.gitbook.io/advanced-views/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://wplake.gitbook.io/advanced-views/layouts/code-fields/javascript-code/shadow-dom-mode.md).

# Layout Shadow DOM mode

By default, in Advanced Views, every [*Layout*'s JavaScript](/advanced-views/layouts/code-fields/javascript-code.md) is turned into a classic Web Component. In this mode, the component behaves like a regular HTML element, meaning global CSS rules—such as `p { color: blue; }`—can affect its internal markup.

To isolate your component from the rest of the page, you can enable the **Shadow DOM** option. This uses the native[ Shadow DOM feature](https://developer.mozilla.org/en-US/docs/Web/API/Element/attachShadow) of Web Components to encapsulate the component's markup and styles. As a result, global CSS no longer affects the component's internal elements, and only the Layout's CSS is applied.

Think of it as rendering your *Layout* on a clean canvas, free from the surrounding page's styles.

## 1. How to enable *Layout* Shadow DOM

* [Create a new *Layout*](/advanced-views/getting-started/first-layout.md) or open an existing one
* On the *Layout* edit screen, switch to the *Options* tab.
* **Choose** one of the Shadow DOM options (compared in the section below)
* **Click** on the **Update** button to publish your changes.

{% hint style="info" %}
Note: when Shadow DOM is enabled, your JavaScript must query elements through the component's shadow root instead of the component itself. Therefore, don't forget to replace all `this` usages with `this.shadowRoot`
{% endhint %}

## 2. Use cases of Shadow DOM

Shadow DOM is especially useful when integrating a *Layout* into an existing website with unpredictable or poorly scoped CSS.

On well-structured websites that follow a modular CSS approach, the default **Classic** mode is often sufficient. However, many legacy sites contain extensive global styles that unintentionally affect new components.

Without Shadow DOM, you may need to spend considerable time overriding those styles. Even styling something as simple as a `<ul>` can become frustrating due to inherited rules and CSS specificity.

With Shadow DOM enabled, those global styles are isolated from your component, eliminating the need for most overrides and making your Layout much easier to develop and maintain.

## 3. Types of Shadow DOM

There are two ways to create a Shadow DOM:

1. **Declarative Shadow DOM** (using a `<template>` element)
2. **Imperative Shadow DOM** (created with JavaScript)

Advanced Views supports both approaches. Although they both provide style and markup encapsulation, they differ in browser support, rendering behavior, and use cases.

The comparison table below will help you choose the most suitable option:

| Type                   | Description                                                                                                                                                                                                                                                                                               | Best use cases                                                                                                                                                             | Limitations                                                                                                                                                                                                    |
| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Declarative Shadow DOM | <p>Made using the <a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_shadow_DOM#declaratively_with_html">\<template></a> tag, which is added on the server side. <br><br>The element will be rendered before the JavaScript is loaded.</p>                                    | *Layouts* that are available on the page since loading.                                                                                                                    | <p>Parsed only once, on page load. <br><br>This means elements with this option can't be added later, e.g., via AJAX (like <em>Layout</em> inside the "Load More" of <em>Post Selection</em>).</p>             |
| Imperative Shadow DOM  | <p>Made using the <a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_shadow_DOM#imperatively_with_javascript">attachShadow</a> method call. <br><br>The element will be rendered as plain HTML and turned into a Shadow DOM on the client side when JavaScript is loaded.</p> | <p><em>Layouts selected for</em> <em>Post Selections</em> with the pagination feature active. <br><br>Any <em>Layouts</em> added to the page after it has been loaded.</p> | <p>May cause minor layout shifts or visual differences during loading:<br><br>All the page styles are applied to the element before JavaScript is loaded and are disabled only after JavaScript is loaded.</p> |

## 4. Global styles workaround

E.g. Tailwind styles are dynamically merged on the page level to avoid class duplication. This means that by default, they won't be included inside elements with the WebComponent Shadow type. However, you can use a workaround to achieve the same experience.&#x20;

Let's review the following case: we have a page and need to add four elements styled with Tailwind. Meanwhile, we need to avoid Tailwind styles appearing at the page level (the default behavior). To achieve this, we can wrap our elements in a *Layout* and define a special comment, which will instruct Advanced Views to place the page styles there. See the example below:

```html
<my-page>
    <template shadowrootmode="open">
        <!--advanced-views:styles/custom-location-->
        <div>
            <div class="flex flex-col font-lato">
                [avf-layout name="One block" id="669137a4e4654"]
                [avf-layout name="Another block" id="669138190e3ca"]
            </div>
        </div>
    </template>
</my-page>

```

In this case, we can use Tailwind for any elements, *Layouts* inside this element, and Tailwind CSS styles won't appear at the page level.

{% hint style="info" %}
**Tip:** You may need to insert a third-party element between the elements. For example, some form that is already styled by the theme or plugin and needs to be available for JavaScript globally. For this case, you can use the [Slots](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_templates_and_slots#adding_flexibility_with_slots) feature, as shown in the example below:
{% endhint %}

```html
<my-page>
    <template shadowrootmode="open">
        <!--advanced-views:styles/custom-location-->
        <div>
            <div class="flex flex-col font-lato">
                [avf-layouts name="One block" vid="669137a4e4654"]
                <slot name="ninja-form"></slot>
                [avf-layouts name="Another block" id="669138190e3ca"]
            </div>
        </div>
    </template>
    <div slot="ninja-form">[ninja_form id=1]</div>
</my-page>

```

In this case, the content inside the slot will be inserted between the elements but will remain at the page level, making it available for any global CSS and JavaScript.
