Search code examples
cssgoogle-chrome-extensionshadow-dom

Shadow DOM styles encapsulation


I want to create a Chrome extension which will inject a widget into a web page.

My widget must have a consistent style when injected on any page. Afaik, the best way to achieve this is to use Shadow DOM.

It seems that by design Shadow DOM styles inherits from parent's page styles. One have to use all:initial CSS property for host element to prevent parent page's styles leak into the shadow DOM styles.

So, I have a sample code:

(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>
  `;
}());

If you open Chrome's dev tools and execute this code in the console, it'll work as expected on most websites. But on some websites (like reddit.com) the styles are still inherited from the parent page.

reddit.com-vs-example.com

What changes I have to make to be sure that the widget's styles will be consistent across all web pages.


Solution

  • wOxxOm gave the correct answer:

    Use mount.style.cssText='all:initial' instead of :host