Инкапсуляция стилей Shadow DOM - PullRequest
0 голосов
/ 15 ноября 2018

Я хочу создать расширение Chrome, которое будет вставлять виджет в веб-страницу.

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

Кажется, что стили Shadow DOM наследуются от стилей родительской страницы. Необходимо использовать all:initial свойство CSS для хост-элемента, чтобы предотвратить утечку стилей родительской страницы в стили теневой DOM.

Итак, у меня есть пример кода:

(function addWidget() {
  let rootEl = document.querySelector('body');
  let mount = document.createElement('div');
  rootEl.appendChild(mount);
  let shadowRoot = mount.attachShadow({mode: 'open'});
  shadowRoot.innerHTML = `
<style>
:host {
all: initial;
}

div {
position: fixed;
z-index: 2147483647;
border: 1px solid black;
padding: 30px;
font-size: 30px;
background: tomato;
top: 10px;
right: 10px;
}
</style>

  <div>Shadow DOM</div>
  `;
}());

Если вы откроете инструменты разработчика Chrome и выполните этот код в консоли, он будет работать, как и ожидалось, на большинстве веб-сайтов. Но на некоторых веб-сайтах (например, reddit.com) стили по-прежнему наследуются от родительской страницы.

reddit.com-vs-example.com

Какие изменения я должен внести, чтобы быть уверенным, что стили виджета будут одинаковыми на всех веб-страницах.

1 Ответ

0 голосов
/ 16 ноября 2018

wOxxOm дал правильный ответ:

Использовать mount.style.cssText = 'all: initial' вместо: host

...