配样式配了八年,今天才发现 CSS 终于能认「前缀」这件事了——.btn-* 把这件事彻底原生化了

配样式配了八年,今天才发现 CSS 终于能认「前缀」这件事了——.btn-* 把这件事彻底原生化了

以前给一组按钮写样式,.btn-primary、.btn-danger、.btn-success……每个都要单独列一遍,或者老老实实加一个 .btn 基类。现在不用了,八月 CSSWG 在柏林开会,刚刚把 Class Prefix Selector 写进了 Selectors Level 5 规范,语法就一行:

.btn-* {
  padding: 0.5rem 1rem;
  border-radius: 4px;
}

这个 -* 就是前缀选择器,它会匹配所有以 btn- 开头的 class,.btn-primary、.btn-danger、.btn-success 全部命中。不用列名单,不用加基类,一行解决。

光写规范不够,有人才有这个需求。Lea Verou 早在 2024 年就在 GitHub 上提了这个想法(w3c/csswg-drafts/#10001),两年后终于落地。规范文本说得很清楚:只会匹配前缀后面至少还有一个字符的情况,单独的 .btn- 不会命中,.btn–primary 也不会。横杠分隔符是必须的,.foo* 这种任意通配不考虑——因为会误匹配 .footer,浏览器做 class 匹配的性能优化也会被破坏。

有人问为什么不直接复用 |= 属性选择器(比如 [class|=”btn”])。官方回复是,这个选择器本来就是给 lang 属性设计的(匹配 en 和 en-us),直接拿过来会有三个问题:它会误匹配独立的 .bi 基类;它在多 class 场景下完全失效(因为只检查属性值开头);而且从长远看,CSSWG 正在推进通配符标准化的更大计划,.- 这套语法以后还能扩展到属性名通配([data-])和自定义元素名通配(custom-framework-*),|= 受限于属性值,撑不起这个 bigger picture。

还有一个关键数据是性能。有人跑了基准测试,普通 class 选择器一秒能跑 6000+ 次,而 [class*=” btn-“] 这种属性子串匹配直接掉到 328 次,慢了将近 20 倍——每一次匹配大约吃掉了 3ms 的帧预算。官方选择 class prefix selector 而不是属性选择器,性能是一个重要原因,浏览器可以为 class 前缀做索引 bucket,不用每次都扫描整个字符串。

目前这个功能还比较新,规范写好不到两周,Chromium、Firefox、Safari 都还没有实现跟进,Chromium 的 bug 单是 CrBug #550093337,想跟踪进展可以订阅。@supports 选择器检测可以先用上:

@supports selector(.foo-*) {
  .btn-* {
    padding: 0.5rem 1rem;
    border-radius: 4px;
  }
}

实际上线还得等。规范正式落地之前,样式表里还是要继续用老办法:列名单,或者加基类。但这个方向是确定的——CSS 终于开始系统性地处理「前缀」这个在设计系统和组件库里非常常见的命名模式了。明年这个时候,大概就能在生产环境里把它用起来了。

评论区

0 条评论

登录后可评论。

小鹿·界面实验室 173 阅读