介绍

比如,自定义了一个按钮:

1
<ui-button type="primary">按钮</ui-button>

如何在外部修改已定义的 Web Components 的 Shadow DOM 内部样式?下面是两种方法。

使用 CSS 变量

在 Shadow DOM 内部使用 CSS 变量定义样式,然后在使用 Web Components 的地方改变 CSS 变量的值即可改变 Shadow DOM 内部样式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class UiButton extends HTMLElement {
constructor() {
super();
const shadow = this.attachShadow({ mode: 'open' });
shadow.innerHTML = `
<style>
button {
padding: 9px 1em;
border: 1px solid;
border-radius: var(--ui-button-radius, 4px);
background: var(--ui-button-background, #fff);
color: var(--ui-button-color, #333);
border-color: var(--ui-border-color, #ccc);
}
</style>
<button part="button">${this.textContent}</button>`;
}
}
customElements.define('ui-button', UiButton);
1
2
3
4
5
6
[type=primary] {
--ui-button-radius: 1mm;
--ui-button-background: deepskyblue;
--ui-button-color: #fff;
--ui-border-color: lightblue;
}

使用 ::part 伪元素

::part CSS 伪元素表示在 Shadow DOM 中任何匹配 part 属性的元素。只需要在 Shadow DOM 中元素上添加 part 属性,然后在外部使用 ::part 伪元素选择匹配 part 属性的元素改变样式即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class UiButton extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' }).innerHTML = `
<style>
button {
padding: 9px 1em;
border: 1px solid #ccc;
border-radius: 4px;
background: #fff;
color: #333;
}
</style>
<button part="button">${this.textContent}</button>`;
}
}
customElements.define('ui-button', UiButton);
1
2
3
4
5
[type=primary]::part(button) {
border-color: coral;
background: orangered;
color: #fff;
}
  1. part 全局属性包含一个以元素中 part 属性名称组成的列表,该列表以空格分隔。
  2. 在任意元素(包括 HTMLUnknownElement)上,element.part 都会返回一个 DOMTokenList 对象。所以判断一个元素是否含有 part 属性,不能使用 element.part,要用 Element.hasAttribute('part') 方法。
  3. 可以通过 DOM 事件改变 part 属性的值,来动态改变伪元素 ::part 选择的元素的 CSS 样式:

浏览器支持

在安卓手机,苹果手机和 PC 端测试,都可以完全支持,查看到效果。而 is 属性目前只有 Safari 浏览器不支持。

developer.mozilla.org_en-US_docs_Web_CSS___part.png

CPT2210211722-617x293.png