Javascript 从外部设置阴影DOM样式

Javascript 从外部设置阴影DOM样式,javascript,css,html,styling,shadow-dom,Javascript,Css,Html,Styling,Shadow Dom,我正在寻找一种从外部设置阴影DOM样式的方法。例如,我想将所有“span.special”元素中所有文本的颜色设置为红色。包括来自阴影DOM的“span.special”元素。我怎么能做到 以前有:shadow伪元素和/deep/组合子aka>用于此目的。所以我可以写一些像 span.special, *::shadow span.special { color: red } 但是现在,::shadow、/deep/和>被弃用。那么,我们有什么可以替代它们呢 您可以使用@import

我正在寻找一种从外部设置阴影DOM样式的方法。例如,我想将所有“span.special”元素中所有文本的颜色设置为红色。包括来自阴影DOM的“span.special”元素。我怎么能做到

以前有:shadow伪元素和/deep/组合子aka>用于此目的。所以我可以写一些像

span.special, *::shadow span.special {
    color: red
}

但是现在,::shadow/deep/>被弃用。那么,我们有什么可以替代它们呢

您可以使用@import css,如本文中所述,以解决其他问题

在阴影树的样式元素中包含规则


@导入url('/css/external styles.css')


请注意,@import仍然是CSS作用域模块草案的一部分。

如果您使用的是无法更改的库web组件,@import不是一个解决方案

最后我找到了几种方法:

1) 层叠。shadowdom的宿主元素的样式也会影响shadowdom元素。如果您需要对shadowdom的特定元素进行样式设置,则这不是一个选项,而不是每个元素

2) 自定义属性 如果web组件的作者提供了这样的信息

3) 在聚合物中,也有定制的混合物

4) @import,但仅适用于非库组件


因此,有几种可能性,但都是有限的。没有像::shadow那样强大的外部样式化方法。

我尝试了很多方法,包括这里描述的方法。因为我使用的是外部Web组件库,所以我没有修改这些组件的权限。因此,唯一适合我的解决方案是使用JS
querySelector
,如下所示:

document.querySelector("the-element.with-shadow-dom")
  .shadowRoot.querySelector(".some-selector").setAttribute("style", "color: black");
不是最好的解决方案,不适用于大型样式,但确实适用于小型增强

@John这是用Chrome 83.0.4103.116测试的(仍将在Safari中测试),我是用Ionic(v5)
ion toast
组件测试的。以下是我使用的(几乎)真实代码:

从'@ionic/core'导入{toastController};
让toatstopts={
消息:“这里有消息。”,
cssClass:“带垂直按钮的烤面包”,
按钮:[
{
文字:“按钮1”,
侧面:“结束”
},
{  
文本:“按钮2”,
侧面:“结束”
},
{
图标:“关闭”,
侧面:“开始”
}
]
}
toastController.create(toastOpts).then(异步p=>{
let toast=wait p.present();//这将呈现ion toast组件并返回HtmlOnToast元素
toast.shadowRoot.querySelector('div.toast-button-group-end').setAttribute(“样式”,“弹性方向:列”);
});

穿透阴影根仍然没有简单的方法,但这里有三种方法可以做到这一点。请记住,您需要在web组件内部进行更改

  • 使用变量v1-您需要在web组件内传递属性并使用变量

  • 使用变量v2-您需要在web组件中使用变量

  • 使用
    ::part()
    -您需要向要在web组件中设置样式的元素添加part属性。(注意:这个伪元素得到了很好的支持,但仍然处于实验模式,所以在生产中使用它之前,请确保您知道这一点)

  • 有关详细信息,请运行下面的代码示例

    constela=document.querySelector('custom-container-a');
    const shadowRootA=elA.attachShadow({mode:'open'});
    shadowRootA.innerHTML=':host([border]){display:block;border:var(--custom border);}'+
    “阴影内容A

    ” const elB=document.querySelector('custom-container-b'); const shadowRootB=elB.attachShadow({mode:'open'}); shadowRootB.innerHTML='p{display:block;color:var(--自定义颜色,蓝色);}'+ “阴影内容B

    ” const elC=document.querySelector('custom-container-c'); const shadowRootC=elC.attachShadow({mode:'open'}); shadowRootC.innerHTML='

    Shadow内容C

    '
    /*常规样式*/
    p{
    颜色:橙色;
    }
    /*使用变量版本1*/
    定制容器{
    --定制边框:3件纯金;
    }
    /*使用变量版本2*/
    定制集装箱{
    --定制颜色:绿色;
    }
    /*使用::part()注意:这方面的规范尚未最终确定。
    因此,在生产中使用它可能不是一个好主意*/
    custom-container-c::part(段落){
    颜色:洋红色;
    }
    光含量


    您能否提供一个通用HTML5元素的示例,并说明它在哪些浏览器中工作?虽然我只对
    input
    元素和Waterbox 56之类的阴影DOM的样式感兴趣,但似乎是可行的。不过,我还没有看到其他人发布过像您这样的代码,谢谢。阴影部分现在得到了相当好的支持:
    document.querySelector("the-element.with-shadow-dom")
      .shadowRoot.querySelector(".some-selector").setAttribute("style", "color: black");