介绍下与CSS自定义组件相关的:state()函数

这篇文章发布于 2025年11月17日,星期一,15:48,归类于 CSS相关。 阅读 120 次, 今日 119 次 没有评论

 

一、你需要提前知道的

Web Components组件开发又新增新特性,为:state()伪类函数。

4年多前,有介绍过::part()伪元素函数,可以穿透组件内部,对里面的样式进行设置。

详见这篇文章:“使用::part伪元素改变Shadow DOM的CSS样式

:state()伪类函数,则是穿透组件内部,匹配状态进行样式设置。

你可以理解为,::part()伪元素函数更像是 [disabled] 这种属性选择器,需要内部HTML有对应的属性设置(通过设置part属性)才能匹配,但是:state()伪类函数更像是 :disabled 这类伪类选择器,看中的是元素的真实状态,而非是否有这个属性。

attachInternals方法

那如何给组件设置状态,让:state()伪类函数匹配呢?这个就需要用到今年年初介绍的attachInternals方法。

可以访问这里了解:“研究下attachInternals方法,可让普通元素有表单特性

例如:

const someInternals = someCustomElement.attachInternals() 

而这个someInternals就是个ElementInternals对象,其包含一个名为states的属性(见下图)。

status语法

states属性的返回值是一个CustomStateSet对象,包含以下一些属性和方法:

// 属性
CustomStateSet.size
// 方法
CustomStateSet.add()
CustomStateSet.clear()
CustomStateSet.delete()
CustomStateSet.entries()
CustomStateSet.forEach()
CustomStateSet.has()
CustomStateSet.keys()
CustomStateSet.values()

我们日常开发,用的比较多的讲就是add()方法添加状态,delete()方法删除状态。

二、:state()函数案例

一例胜千言,让我想想,弄个什么案例好呢……要经典,又要具有代表性,嗯……算了,随便示意下效果吧。

JS和CSS代码如下所示:

class UiLoading extends HTMLElement {
  constructor() {
    super();

    const internals = this.attachInternals();
    
    this.addEventListener('click', () => {
      internals.states.add('loading');
    
      setTimeout(() => {
        internals.states.delete('loading');
      }, 3000);
    });
    
  }

  connectedCallback() {
    this.click();
  }
}
// 定义自定义组件
if (!customElements.get('ui-loading')) {
  customElements.define('ui-loading', UiLoading);
}
ui-loading {
  display: inline-grid;
  place-items: center;
  width: 150px; height: 150px;
  border: 2px dashed;
}
ui-loading:state(loading) {
  border-color: red;
  background: lightgreen;
}

此时,只要页面上有 <ui-loading> 元素,就可以看到样式变化了。

默认是绿底红框,几秒钟时候,就是黑框了。

实时效果如下所示,如果看不到效果,请点击下面的框框。

可以看到,:state()函数的设计初衷就是为了方便暴露组件内部的状态。

例如,选中与否,失败与否,加载与否等。

三、兼容性与结语

CSS :state()伪类函数在2024年5月份的时候,已经被所有现代浏览器都支持,大规模应用的时机还不成熟,不过不得不说,这个东西可以提高组件开发的档次感(虽然part属性和::part()函数也能实现类似效果,但没有这个看起来高大上)。

:state()函数兼容性

总结

:state() 伪类是未来 Web 组件样式化的一个强大且语义化的工具。它将样式控制的逻辑从“如何渲染”(暴露内部部件)转变为“在什么状态下渲染”,使得组件开发者能更好地封装内部结构,同时为组件使用者提供清晰、强大的样式定制能力。

吐槽

昨天遇到个难受的事情,我鱼竿包里翻来覆去,我的一根鱼竿不见了,达亿瓦一击枫,是我买的价格比较高的杆子之一,用了很多年了,也比较有感情了。

思来想去,是上周在情人谷垂钓园钓鲫鱼的时候,没有及时收起来,搁在了河边,走的时候,只收了另外一只杆子,同时损失的还有一只浮漂。

好难受,钓鱼这么多年,还是头一次丢杆子。

打电话给老板,老板也没见到,估计被人捡走了。

郁闷!

鱼没有钓到几条,杆子没了,我都不敢告诉家里人,不然又要吐槽丢三落四,只能悄悄又买了个新杆子。

舍不得买贵的,就买了个200不到的,唉……

哭泣

(本篇完)

分享到:


发表评论(目前没有评论)