JavaScript ShadowRoot — тіньовий DOM і ізоляція стилів


ShadowRootтіньове дерево всередині елемента: власний DOM, у який не проникають зовнішні стилі й з якого не витікають свої.

автор: NagarD

Загальний опис

Це справжня інкапсуляція, якої CSS не мав ніколи. Клас .title усередині тіні не зіткнеться з класом .title на сторінці — це два різні світи.

Створюється через element.attachShadow({ mode: 'open' }). Далі всередину кладеться і розмітка, і <style> — і цей стиль діє лише тут.

Саме на цьому побудовані веб-компоненти: віджет можна вставити на будь-який сайт, і його вигляд не зламається чужим CSS.

І звідси ж головна пастка: document.querySelector() не бачить нічого всередині тіні. Шукати треба від кореня: shadowRoot.querySelector().

автор: NagarD

Нотатка

mode: 'closed' ховає тінь навіть від власного коду (element.shadowRoot дасть null). Захисту це не додає — обійти можна — а налагодження ускладнює, тож майже завжди беруть open.

автор: NagarD

Синтаксис

const shadow = element.attachShadow({ mode: "open" });

властивості

Властивість Опис
host Елемент-хост цього тіньового дерева.
mode Режим доступу: open або closed.
innerHTML Розмітка тіньового дерева.
activeElement Сфокусований елемент усередині тіньового дерева.
delegatesFocus Чи делегується фокус першому фокусованому нащадку.

Переглядачі

Підтримка: стаціонарні переглядачі
Переглядач Google Chrome Mozilla Firefox Apple Safari Opera Microsoft EDGE Microsoft Internet Explorer
ShadowRoot 53+ 63+ 10+ 40+ 79+ -
Підтримка: мобільні переглядачі
Переглядач Mobile Google Android Mobile Google Chrome Mobile Mozilla Firefox Mobile Apple Safari
ShadowRoot 53+ yes yes 10+

Приклади

+ запропонувати свій приклад у пісочниці

Компонент, чиї стилі не б'ються зі стилями сторінки.

HTML

<style>.title { color: red; }</style>
<div id="host"></div>
<p class="title">Я червоний — стиль сторінки</p>

JS

const host = document.getElementById('host');
const shadow = host.attachShadow({ mode: 'open' });

shadow.innerHTML = `
    <style>
        /* діє ЛИШЕ тут — не зіткнеться з .title сторінки */
        .title { color: green; font-weight: bold; }
    </style>
    <p class="title">Я зелений — стиль тіні</p>
`;

// сторінка тіні не бачить
console.log(document.querySelectorAll('.title').length); // 1, а не 2

// шукати треба від кореня тіні
console.log(shadow.querySelector('.title').textContent);
автор: NagarD

Коментарі

Коментарів ще немає — будьте першим!

Відповідь для

Увійдіть — коментар з'явиться одразу, без капчі й очікування перевірки.

Пропозиція правки

Ваша версія — : після перевірки замінить чинну. Нова порада чи нотатка — з'явиться на сторінці після перевірки.

Ви гість — діють добові ліміти. Увійдіть, щоб пропонувати без капчі.

Ваша версія секції «»: після перевірки замінить чинну.

Ви гість — діють добові ліміти. Увійдіть, щоб пропонувати без капчі.

Ваша версія опису «»: після перевірки замінить чинну.

Ви гість — діють добові ліміти. Увійдіть, щоб пропонувати без капчі.

Зворотний зв'язок
Вхід