我正在寻找从外部设置阴影DOM样式的方法。例如,我想设置所有文本的颜色&span; span.special'元素为RED。包括&span; span.special'来自shadow DOM的元素。我怎么能这样做?
此前,为此目的, :: shadow 伪元素和 / deep / 组合器又名>>> 。所以我可以写点像
span.special, *::shadow span.special {
color: red
}
但现在不推荐使用 :: shadow , / deep / 和>>> 。那么,我们有什么替代它们?
答案 0 :(得分:4)
你可以使用@ answer中解释的@import css来解决另一个关于SO的问题。
将规则包含在阴影树中的 style 元素中。
<style>
@import url( '/css/external-styles.css' )
</style>
请注意,>>> combinator仍然是CSS范围模块草案的一部分。
答案 1 :(得分:4)
嗯,如果您正在使用无法更改的库Web组件,@ import不是解决方案...
最后我找到了几种方法:
1)级联。 Shadow DOM的主机元素的样式也会影响Shadow DOM元素。如果您需要为Shadow DOM的特定元素设置样式,而不是每个元素都不是一个选项。
2)自定义属性https://www.polymer-project.org/1.0/docs/devguide/styling 如果Web组件的作者提供了此类。
3)在Polymer中,Custom Mixins也是https://www.polymer-project.org/1.0/docs/devguide/styling
4)@ import,但仅适用于非库组件
所以,有几种可能性,但所有这些都是有限的。没有足够强大的外部造型方式,如:: shadow are。
答案 2 :(得分:1)
我确实尝试了许多方法,包括此处描述的方法。由于我使用的是外部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
组件进行了测试。这是我使用的(几乎)真实代码:
import { toastController } from '@ionic/core';
let toastOpts = {
message: "Some message goes here.",
cssClass: "toast-with-vertical-buttons",
buttons: [
{
text: "Button 1",
side: 'end'
},
{
text: "Button2",
side: 'end'
},
{
icon: "close",
side: "start"
}
]
}
toastController.create(toastOpts).then(async p => {
let toast = await p.present(); // this renders ion-toast component and returns HTMLIonToastElement
toast.shadowRoot.querySelector('div.toast-button-group-end').setAttribute("style", "flex-direction: column");
});
答案 3 :(得分:1)
仍然没有简单的方法可以刺穿阴影根部,但您可以通过以下 3 种方法进行操作。请记住,您需要在 Web 组件内部进行更改。
使用变量 v1 - 您需要传递该属性并在 Web 组件内使用该变量。
使用变量 v2 - 您需要在 Web 组件内使用该变量。
使用 struct Message: Decodable {
let command: String
let data: String
}
- 您需要向要在 Web 组件中设置样式的元素添加部件属性。 (注意:这个伪元素得到了很好的支持,但仍处于实验模式,所以在生产中使用它之前请确保你知道这一点)。
运行下面的代码示例以了解详细信息。
::part()
const elA = document.querySelector('custom-container-a');
const shadowRootA = elA.attachShadow({mode:'open'});
shadowRootA.innerHTML = '<style>:host([border]) {display:block;border: var(--custom-border);}</style>'+
'<p>Shadow content A</p>'
const elB = document.querySelector('custom-container-b');
const shadowRootB = elB.attachShadow({mode:'open'});
shadowRootB.innerHTML = '<style>p {display:block;color: var(--custom-color, blue);}</style>'+
'<p>Shadow content B</p>'
const elC = document.querySelector('custom-container-c');
const shadowRootC = elC.attachShadow({mode:'open'});
shadowRootC.innerHTML = '<p part="paragraph">Shadow content C</p>'
/* Normal way of styling */
p {
color: orange;
}
/* Using variables version 1 */
custom-container-a {
--custom-border: 3px solid gold;
}
/* Using variables version 2 */
custom-container-b {
--custom-color: green;
}
/* Using ::part() NOTE: The specs for this hasn't been finalized.
So it might not be a good idea to use in production. */
custom-container-c::part(paragraph) {
color: magenta;
}