CSS 这个新伪类让我把组件状态同步的全删了——容器状态终于能被 CSS 直接读懂了

写过 CSS 响应式组件的人,大概都遇到过这个尴尬时刻——容器的尺寸变了,但你只能靠 JavaScript 去监听 resize 事件,然后再手动更新子组件的样式。CSS 明明知道容器发生了什么,却把这些信息藏着不告诉你。

这个局面,现在被一个叫 :state() 的新伪类彻底改变了。

## 容器状态,终于能被 CSS 直接感知了

CSS 社区把 :state() 叫做 Container State Queries(容器状态查询),它允许你直接在 CSS 里写这样的规则:

@container style(--is-collapsed: true) {
  .card { padding: 8px; }
}

子组件不需要知道父容器有没有某个 class、某个 data 属性,只需要说”当父容器 –is-collapsed 这个变量为 true 时,我就用这套样式”。

这听起来有点像 CSS 变量配合 :has(),但本质区别在于:变量是可以动态设置的,而 :state() 专门设计来让浏览器本身的变化状态能被 CSS 直接读取。

## 三个真实场景,它能干什么

**第一个:折叠面板。** 传统做法是父组件加一个 is-collapsed class,然后子组件通过 class 名匹配来决定是否显示。这套逻辑现在可以变成纯粹的状态注入:

.panel { container-type: state; }
@container style(--panel-state: collapsed) {
  .panel-body { display: none; }
}

**第二个:虚拟列表。** 当容器判断自己”滚动到了底部”,可以把这个状态写成一个 CSS 变量,下面的”加载更多”按钮自动感知:

@container style(--at-bottom: true) {
  .load-more { opacity: 0.5; pointer-events: none; }
}

**第三个:表单验证状态穿透。** 表单域的验证状态(valid/invalid/pending)可以在容器层面用变量标记,子元素不需要 JavaScript 就能切换样式。

## 它和 :has() 怎么选

:has() 解决的是”选择器能不能看到父级”的问题,而 :state() 解决的是”样式逻辑能不能看到组件内部状态”的问题。

一个简单的判断标准:如果你的组件样式变化只需要判断”父容器有没有某个 class”,用 :has();如果需要判断”父容器的某个动态状态值是什么”,用 :state()。

## 现状和下一步

目前 :state() 还在 CSS Conditional Rules Level 5 规范的草案阶段,Chrome 正在积极推进实现。根据 CSS 工作组的讨论记录,这个特性的设计目标就是让组件在完全不依赖 JavaScript 样式逻辑的情况下,也能对父容器状态变化做出响应。

换句话说,这不只是又加了一个伪类——它代表了一种新的响应式思路:让浏览器自己的状态变化,成为 CSS 样式变化的触发器,而不需要 JavaScript 在中间传话。

如果你所在的团队组件层级深、状态同步逻辑复杂,这个能力值得密切关注。用不了太久,你可能真的会删掉很多 ResizeObserver 里的 element.style.xxx。

评论区

0 条评论

登录后可评论。

AI 论文日报 11 阅读