I am trying to create a Chrome extension with a floating widget. To do that, I have to isolate my element from the rest of the page. Shadow DOM looks like a perfect fit for that, but it isn't doing what I expected.
Here is my content script:
content.js
var lightDom = document.createElement('style');
lightDom.innerText = 'div { color: red }';
document.body.appendChild(lightDom);
var shadowDom = document.createElement('div');
document.body.appendChild(shadowDom);
var shadowRoot = shadowDom.attachShadow({'mode': 'open'});
shadowRoot.innerHTML = `
<style>
div {
background-color: blue;
}
</style>
<div>Shadow!</div>
`;
The div inside the shadow DOM should have black text, but it has red text instead. Am I doing something wrong?
Shadow DOM allows hidden DOM trees to be attached to elements in the regular DOM tree — this shadow DOM tree starts with a shadow root, underneath which you can attach any element, in the same way as the normal DOM.
Shadow DOM permits encapsulation of styling rules for custom elements. You can freely define styling information for your elements, such as fonts, text colors, and classes, without fear of the styles applying outside the scope of your element.
In Chrome: Press F12, DevTool will open. Click gear icon in DevTool. Uncheck "show user agent shadow DOM" checkbox.
With shadow DOM, CSS styles defined in a parent component don't apply to a child component. Contrastingly, light DOM enables styling from the root document to target a DOM node and style it. The styles on the following native shadow component cascades into the child component's light DOM.
CSS selectors in Light DOM are prevented from reaching elements inside shadow DOM. But when a CSS property has the value inherit
, which is the default value of color
, the shadow DOM will still inherit those from the light DOM.
From the CSS Scoping specification
3.3.2 Inheritance
The top-level elements of a shadow tree inherit from their host element. The elements in a distribution list inherit from the parent of the content element they are ultimately distributed to, rather than from their normal parent.
You can prevent the values of properties form being inherited by using the initial
value.
From the CSS Cascading and Inheritance specification
7.3.1. Resetting a Property: the initial keyword
If the cascaded value is the initial keyword, the property’s initial value becomes its specified value.
The initial value of each property is documented in the specification it is defined in. color
is documented in the CSS Color specification and its initial value is depends on user agent
, for most user agents this will be black
.
You can assign initial
to each property you don't want to inherit its value. Or you can set the value of all
to initial
, like so:
.selector
{
all: initial;
}
The all
property is defined as follows in the same spec as the initial keyword.
3.1. Resetting All Properties: the all property
The all property is a shorthand that resets all CSS properties except direction and unicode-bidi. It only accepts the CSS-wide keywords.
"CSS-wide keywords" is defined in CSS 3 values specification in section 3.1.1, but comes down to the values initial
, inherit
and unset
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With