摘要
- W3C 2018 年 2 月草案写下一个尚未命名的零权重选择器;同年 11 月,它以
:where()之名出现,并用链接下划线的冲突示范用途。 :where()里的条件继续参与匹配,却不给选择器增加权重。括号外的类名、元素名仍照常计分;这让通用样式可以准确,也可以好改。
导航栏里那条链接并没有犯错。通用样式先写了 a:not(:hover),让鼠标没有悬停的链接不带下划线。负责导航栏的人写下 nav a,想把下划线补回来。按直觉,两条规则都选中链接,后写的导航规则该说了算。CSS 却翻出记分牌:前者的伪类加元素,比后者的两个元素选择器更重。把导航规则搬到文件最末尾也没用。于是有人开始加类名、叠伪类,最后祭出 !important,仿佛一根下划线需要动员全公司。
这不是编出来吓新人的事故。它来自 W3C 2018 年 11 月 21 日的 Selectors Level 4 草案。草案给出的改法只有一处:把通用规则写成 a:where(:not(:hover))。未悬停的链接仍会被选中;:not(:hover) 放进 :where() 后,不再给权重添码。括号外的 a 还占一个元素选择器的分量,nav a 则有两个。导航作者不必揣测通用规则为什么这样写,就能在自己的场景里把下划线放回去。
这套办法先有想法,后有名字。2018 年 2 月 2 日草案 的变更记录已提到一个类似 :matches()、权重为零的伪类,但名字仍待确定。11 月草案才把它叫做 :where();CSS 工作组随后发布的说明 也明确列出了这个新名字。问题并非浏览器不会找元素。CSS 早就会找。真正棘手的是:通用规则找到元素后,要不要顺势占住未来的决定权。
选择器平日把两件事绑在一起:匹配谁,以及冲突时谁更有分量。:where() 让作者把这两件事分开。设计系统可以用复杂条件认出组件,再主动降低这些条件在权重赛里的存在感。2022 年 5 月 7 日草案 给出一眼就懂的算式:.qux:where(em, #foo#bar#baz) 的权重是 (0,1,0)。括号里那串吓人的 ID 负责筛选,括号外的 .qux 仍贡献一个类的分数。零权重说的是函数和它的参数,不是把整条规则洗成白纸。
这是共享样式的一种礼貌。基础样式必须有足够的辨认能力,才不会误伤别的元素;但它也可以给局部页面留出改动余地。浏览器负责执行共同的匹配和权重规则,写页面的人决定某条默认样式该有多强势。一个团队提供可复用的外观,另一个团队按具体菜单调节它,双方用同一套算术交接工作,不必比谁能写出更长的选择器。
2022 年 11 月 11 日草案 还记录了函数式选择器列表的解析细节:宽容列表可以舍弃无效项,保留有效项。这使条件组合更有弹性,具体行为仍取决于草案规定的语法。:where() 的核心故事始终是权重的自我约束。W3C 的发布时间线 把这一进程钉在 2018 和 2022 年的公开草案上。网页里那根小小的下划线,提醒了所有写共享 CSS 的人:规则可以认得很准,讲话不必很响。
会员简报
档案背景详情
使用相应会员等级登录,即可解锁完整简报与来源注释。
仅限 Strategic Circle
Strategic Circle
所有读者均可浏览。加入并登录后可解锁档案简报。
加入 Strategic Circle仅限 Leadership Alliance
Leadership Alliance
符合条件的 IP 资产所有者和管理层可登录查看 Leadership Alliance 简报。
加入 Leadership Alliance





