CSS 没有完全应用在阴影 DOM 上使用 <slot>

CSS is not fully applying on a shadow DOM using <slot>

我有以下简单组件:

用法:

<style>
        my-element {
            --my-bg: green;
            --my-text: red;
        }
</style>

<my-element myStyling>
        <p>Test</p>
</my-element>

组件:

const template = document.createElement('template');
template.innerHTML = `
<style>
:host([myStyling]), :host([myStyling]) {
    background-color: var(--my-bg);
    color: var(--my-text);
}
</style>
<slot></slot>
      Static
`;
class MyElement extends HTMLElement {

    constructor() {
        super();
        // Attach a shadow root to the element.
        let shadowRoot = this.attachShadow({mode: 'open'});
        shadowRoot.appendChild(template.content.cloneNode(true));
    }
}

window.customElements.define('my-element', MyElement);

代码输出结果如下:

为什么 color: green 适用于静态文本和阴影 DOM 两者,而背景颜色样式仅适用于静态文本?

CCS 属性 color 的默认值是 继承

CSS属性background-color的默认样式是transparent(不会继承其parent 元素).

默认自定义元素 display 属性 是 内联 (= 短语内容),因此不会将背景属性设置为其 child任.

在您的代码中,"Test" 文本位于 <p> 元素中,该元素不会继承 :host 背景颜色,但会是 transparent因此会显示主页的背景色,即white.

有关完整用例,请参阅下面的实际示例。

const template = document.createElement('template')
template.innerHTML = `
  <style>
    :host  {
      background-color: var(--my-bg);
      color: var(--my-text);
    }
  </style>
  <slot></slot>
  <hr>
  Text in Shadow DOM root
  <p>Text in Paragraph in Shadow DOM <span>and child Span</span></p>
  <span>Text in Span in Shadow DOM <p>and child Paragraph</p></span>`
class MyElement extends HTMLElement {
  constructor() {
    super()
    this.attachShadow({mode: 'open'})
        .appendChild(template.content.cloneNode(true))
 }
}
window.customElements.define('my-element', MyElement)
body {
  background-color: lightblue;
}

my-element {
  --my-bg: green;
  --my-text: red;
}
<my-element myStyling>
  Text in Light DOM root
  <p>Text in Paragraph in Light DOM  <span>and Child Span</span></p>
  <span>Text in Span in Light DOM <p>and child Paragraph</p></span>
</my-element>

如果您希望 background-color 应用于 Shadow DOM 内的所有 child 元素,您也必须将 css 规则应用于 * 选择器:

:host, * {
   background-color: ...
}

如果要将 background-color 应用到所有用 <slot> 插入的浅色 DOM 元素,您必须添加 ::slotted(*) pseudo-element 规则:

:host, *, ::slotted(*) {
   background-color: ...
}

替代方法

如果要在文本的不同部分之间应用background-color,请不要伪造将display 属性定义为inline-block or block (= flux content).

因此 all children 将显示根块 background-color。 这是 Shadow DOM:

的完整 <style> 定义
:host  {
    display: inline-block ;
    color: var(--my-text);
    background-color: var(--my-bg);
}