Shadow DOM — это веб-стандарт, который позволяет инкапсулировать и определять область действия стилей и разметки в пределах определенного компонента или элемента, изолируя его от остальной части страницы. Он позволяет создавать многоразовые веб-компоненты с собственным деревом DOM, стилями CSS и поведением JavaScript. Инкапсулированные элементы и стили внутри теневого DOM скрыты от основного документа, что предотвращает вмешательство внешних стилей и скриптов.

то есть: допустим, я создаю пользовательский компонент кнопки под названием «my-button». Используя теневой DOM, вы можете определить HTML-структуру кнопки, стили CSS и функциональность JavaScript в ее собственной инкапсулированной области. На стили компонента не влияют глобальные стили страницы, что обеспечивает единообразие внешнего вида и поведения. Затем другие разработчики смогут использовать ваш компонент «моя кнопка», не беспокоясь о конфликтах с их существующим кодом CSS или JavaScript.

export default function App() {
  useEffect(() => {
    const parentDiv = document.createElement("div");
    const shadowRoot = parentDiv.attachShadow({ mode: "open" });
    shadowRoot.innerHTML=
    `<button id="withShadow">Shadow Button</button>`;

    const buttonStyles = `
    #withShadow {
      background-color: green;
      color: yellow;
      border: none;
      cursor: pointer;
    }
  `;

  const style = document.createElement('style');
  style.textContent = buttonStyles;
  shadowRoot.appendChild(style);
  document.body.appendChild(parentDiv);
  }, []);

  return (
    <>
      <button>Normal Button </button>
    </>
  );
}

На изображении вы можете видеть две кнопки: одна без теневого купола, а другая с включенным теневым домом.
Я применил стиль к кнопке внутри теневого дома, но это не повлияло на стиль всего пользовательского интерфейса.

Почему используется Shadow DOM?

По сути, ответ такой же, как и выше.
Shadow DOM используется для инкапсуляции стилей, структуры и поведения веб-компонента, гарантируя, что он не будет мешать стилям и скриптам веб-компонента или подвергаться их влиянию. окружающая страница. Это позволяет разработчикам создавать автономные компоненты с собственным деревом DOM, стилями CSS и логикой JavaScript, что делает их повторно используемыми и изолированными. Эта инкапсуляция повышает модульность, уменьшает количество конфликтов и повышает удобство сопровождения кода, что приводит к созданию более надежных и масштабируемых веб-приложений.

Какие есть режимы в Shadow DOM?

В Shadow DOM есть три разных режима:

  1. Открытый режим: этот режим позволяет получать доступ к стилям и элементам в Shadow DOM и управлять ими извне компонента.
  2. Закрытый режим: в этом режиме Shadow DOM полностью инкапсулирован, что предотвращает любой прямой доступ или манипуляции извне компонента. Стили и элементы остаются изолированными.
  3. Теневой режим: этот режим похож на закрытый режим, но он также скрывает существование Shadow DOM. Стили и элементы скрыты, что обеспечивает полную инкапсуляцию и конфиденциальность.

Эти режимы обеспечивают гибкость управления доступностью и видимостью Shadow DOM в зависимости от требований веб-компонента.

Каковы преимущества Shadow DOM?

Есть много преимуществ использования теневого DOM, но я упомяну несколько, которые я испытал на практике.

  1. Инкапсуляция: Shadow DOM позволяет нам инкапсулировать стили, структуру и поведение веб-компонента, предотвращая его взаимодействие со стилями и скриптами окружающей страницы или влияние на них.
  2. Модульность. С помощью Shadow DOM компоненты становятся автономными объектами, которые можно повторно использовать в различных частях веб-приложения, обеспечивая модульность и возможность повторного использования кода.
  3. Изоляция. Инкапсуляция, обеспечиваемая Shadow DOM, изолирует компоненты от остальной части страницы, уменьшая количество конфликтов и упрощая управление и поддержку сложных веб-приложений.
  4. Область действия стиля: Shadow DOM гарантирует, что стили CSS, определенные в компоненте, применяются только к элементам внутри компонента, что позволяет избежать непреднамеренных утечек стилей и конфликтов с другими частями страницы.
  5. Улучшенная производительность: Shadow DOM оптимизирует производительность рендеринга, позволяя браузеру эффективно обновлять инкапсулированные компоненты, сводя к минимуму потребность в глобальных перерисовках и перекомпоновках.

Как можно использовать стили в Shadow DOM?

Я нашел четыре способа укладки теневого дома.

1. Внутренний стиль:

const shadowRoot = element.attachShadow({ mode: 'open' });
shadowRoot.innerHTML = `
  <style>
    /* CSS rules specific to the Shadow DOM */
    h1 {
      color: red;
    }
  </style>
  <h1>Hello, Shadow DOM!</h1>
`; 

В этом примере стили определены в теге <style> внутри Shadow DOM. Эти стили будут применяться только к элементам внутри Shadow DOM.

2. Внешние таблицы стилей:

const shadowRoot = element.attachShadow({ mode: 'open' });
const linkElem = document.createElement('link');
linkElem.setAttribute('rel', 'stylesheet');
linkElem.setAttribute('href', 'styles.css');
shadowRoot.appendChild(linkElem);
shadowRoot.innerHTML = `
  <h1>Hello, Shadow DOM!</h1>
`;

Здесь внешняя таблица стилей (styles.css) связана с Shadow DOM с помощью элемента <link>. Стили, определенные во внешней таблице стилей, будут применяться к элементам внутри Shadow DOM.

3. Пользовательские свойства CSS:

const shadowRoot = element.attachShadow({ mode: 'open' });
shadowRoot.innerHTML = `
  <style>
    /* CSS rules using custom properties */
    h1 {
      color: var(--text-color, red);
    }
  </style>
  <h1>Hello, Shadow DOM!</h1>
`;

Пользовательские свойства CSS можно использовать в Shadow DOM для определения гибких стилей и тем. В этом примере цвет элемента <h1> задается с помощью пользовательского свойства --text-color.

4. Использование объекта CSSStyleSheet

const shadowRoot = element.attachShadow({ mode: 'open' });

const stylesheet = new CSSStyleSheet();
stylesheet.replaceSync(`
  h1 {
    color: red;
  }
`);

shadowRoot.adoptedStyleSheets = [stylesheet];

shadowRoot.innerHTML = `
  <h1>Hello, Shadow DOM!</h1>
`;

В этом подходе создается объект CSSStyleSheet и к нему добавляются стили с помощью метода replaceSync(). Свойство adoptedStyleSheets Shadow Root затем используется для применения таблицы стилей к Shadow DOM. Стили, определенные в таблице стилей, будут применяться к элементам внутри Shadow DOM.

Из упомянутых выше стратегий я нашел использование объекта CSSStylesSheet эффективным и простым в использовании.

Заключение

В заключение, Shadow DOM можно использовать для инкапсуляции стилей и разметки компонентов, гарантируя, что остальная часть страницы не повлияет на них. Это способствует повторному использованию и ремонтопригодности кода за счет создания автономных элементов. Доступность и видимость инкапсулированного содержимого можно контролировать с помощью открытого, закрытого или теневого режимов. Кроме того, Shadow DOM повышает производительность, сводя к минимуму глобальные перерисовки и перекомпоновки, а также обеспечивая точную область видимости стилей. В целом, он предлагает эффективное решение для управления стилем компонентов, улучшения организации кода и оптимизации производительности веб-приложений.