I am working on a web extension that adds a custom overlay element to any website. naturally I don't want the websites CSS and JavaScript to interfere with my custom element, nor do I want to influence the appearance of any websites in any way other than with my overlay.
So naturally I turn to Shadow DOM. I soon learn that I can't simply attach my shadow DOM to document.body since this will displace the whole page.
It turns out I need one regular element in the body to act as a shadow root:
const shadowHost = document.createElement('div');
document.body.appendChild(shadowHost);
const shadow = shadowHost.attachShadow({mode: 'closed'});
But how can I protect this shadow root from being influenced by the css or js of the website?
What have you tried?
shadowRoots are not styled by global CSS, unless they are inheritable styles
mode:"closed" has nothing to do with CSS, it just doesn't publish the shadowRoot in element.shadowRoot, making it impossible to access the shadow DOM from the outside.
When the mode of a shadow root is "closed", the shadow root’s implementation internals are inaccessible and unchangeable from JavaScript—in the same way the implementation internals of, for example, the
<video>element are inaccessible and unchangeable from JavaScript.
document.body
.appendChild(document.createElement('div'))
.attachShadow({mode:'closed'})
.innerHTML = `<style>h1{color:green}</style><h1>Hello</h1><h2>Component</h2>`;
<style>
body {
/* inheritable styles do style shadowRoots */
font: 10px Arial;
color: red;
}
</style>