光 DOM 风格渗入阴影 DOM

Light DOM style leaking into Shadow DOM

我正在尝试创建一个带有浮动小部件的 Chrome 扩展。为此,我必须将我的元素与页面的其余部分隔离开来。 Shadow DOM 看起来非常适合它,但它并没有达到我的预期。

这是我的内容脚本:

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>
`;

影子DOM里面的div应该是黑字,但是却变成了红字。我做错了什么吗?

为什么会这样?

CSS Light DOM 中的选择器无法到达阴影 DOM 中的元素。但是当 CSS 属性 的值为 inherit,这是 color 的默认值时,阴影 DOM 仍然会继承光 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.

如何防止它发生?

您可以通过使用 initial 值来防止属性表单的值被继承。

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.

每个 属性 的初始值记录在其定义的规范中。color 记录在 CSS Color specification 中,其初始值为 depends on user agent,对于大多数用户代理,这将是 black.

您可以将 initial 分配给每个您不想继承其值的 属性。或者你可以将 all 的值设置为 initial,像这样:

.selector 
{
    all: initial;
}

all 属性 在与初始关键字相同的规范中定义如下。

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" 在第 3.1.1 节的 CSS 3 values specification 中定义,但归结为值 initialinheritunset