【问题标题】:Styling a child of a shadow root in Shadow DOM在 Shadow DOM 中为影子根的子项设置样式
【发布时间】:2017-03-06 01:37:52
【问题描述】:

我正在尝试为阴影 DOM 根的子元素设置样式。
这定义了一个名为element-el 的自定义元素,它有一个名为“x”的span 类,其中包含字母x,就目前的情况而言,我希望它是红色的。

class El extends HTMLElement {
    constructor() {
        super();
        var shadow = this.attachShadow({mode:'open'});
        shadow.innerHTML = '<span class="x">X</span>';
    }
}
customElements.define ('element-el',El);

我已经尝试过这些 CSS 样式:

element-el::slotted(.x) {
  color:red;
}
element-el::host .x {
  color:red;
}
element-el:host .x {
  color:red;
}
element-el::shadow .x {
  color:red;
}
element-el /deep/ .x {
  color: red;
}
element-el::content .x {
  color:red;
}

X 不会变成红色。 我正在使用 Chrome 56,它应该支持这个...

我想在不将style 元素放入shadow DOM 的情况下对其进行样式设置。
这是一个代码笔: http://codepen.io/anon/pen/OpRLVG?editors=1111

编辑:
This article 建议可以从外部 CSS 文件中设置阴影子项的样式——他们是不是完全错了?

【问题讨论】:

标签: css web-component shadow-dom custom-element


【解决方案1】:

显然问题在于您尝试使用全局 CSS 来设置阴影树元素的样式。

您可以使用:host 伪选择器,但是为了这样做,您必须将样式放在阴影树内容中。

在您的 javascript 中进行以下更改:

class El extends HTMLElement {

    constructor() {
        super();
        var shadow = this.attachShadow({mode:'open'});
        var innerHTML = '';
        innerHTML += '<style>';
        innerHTML += ':host(element-el.red) span {color: red}';
        innerHTML += ':host(element-el.green) span {color: green}';
        innerHTML += ':host(element-el.blue) span {color: blue}';
        innerHTML += '</style>';      
        innerHTML += '<span class="x">X</span>';      
        shadow.innerHTML = innerHTML;
    }

}

customElements.define ('element-el',El);

检查updated codepen 中的功能示例。

【讨论】:

【解决方案2】:

一个简单的解决方案是在 Shadow DOM 中定义 x 类:

class El extends HTMLElement {
    constructor() {
        super()
        this.attachShadow({mode:'open'})
            .innerHTML = `
               <style>
                  .x { color: red } 
               </style>
               <span class="x">X</span>`
    }
}
customElements.define ('element-el',El)
&lt;element-el&gt;&lt;/element-el&gt;

注意:由于 Shadow DOM 的样式封装,您将总是需要在 Shadow DOM 中放置 &lt;style&gt; 元素,无论使用 Romulo 的 :host 解决方案、直接类声明(见上文)或external stylesheet

当然,如果您使用继承的 CSS 属性(如 color),它将适用于所有影子 DOM 内容,您可以只使用普通 CSS:

class El extends HTMLElement {
    constructor() {
        super();
        var shadow = this.attachShadow({mode:'open'});
        shadow.innerHTML = '<span class="x">X</span>';
    }
}
customElements.define ('element-el',El);
element-el {
    color: red;
}
&lt;element-el&gt;&lt;/element-el&gt;   

【讨论】:

  • 感谢您的回答。我在转发这个:developer.mozilla.org/en-US/docs/Web/Web_Components/…,当我认为我可以从外部 CSS 中设置影子 DOM 子项的样式时(请参阅“示例”部分中的“CSS 文件”)——它们在文章中是否完全错误?
  • @YuvalA。是的,::slotted 样式是错误的。它们不起作用,因为它们不在正确的位置(在影子 DOM 的
【解决方案3】:

这可能会对处于类似情况的其他人有所帮助。

在我的情况下,我有:

<svg class="icon">
    <use xlink:href="#my-icon"></use>
</svg>

为了访问#shadow-root 中呈现的图标,我使用:

.icon use {
  fill: #f80;
}

【讨论】:

  • 这有什么关系?
【解决方案4】:

如果 element-el 在 shadow-dom 中,下面的 css 选择器应该可以帮助你:

<parent Element of shadow-root> /deep/ element-el span {
    color:red;
}

选择包含shadow-dom的元素,然后用/deep/选择所有子元素,然后选择span元素。

/deep/ 还不是 HTML 标准,但在 Chrome 和 Firefox 中它应该可以工作。

【讨论】:

  • deep 已被弃用
猜你喜欢
  • 2013-08-21
  • 2021-08-28
  • 2019-04-25
  • 1970-01-01
  • 2019-03-29
  • 1970-01-01
  • 2020-03-16
  • 2014-06-07
  • 1970-01-01
相关资源
最近更新 更多