一聚教程网:一个值得你收藏的教程网站

热门教程

CSS Selectors Level 4里:where和:is区别是什么?

时间:2026-08-29 12:08:47 编辑:袖梨 来源:一聚教程网

:where()与:is()唯一实质区别是权重计算方式不同::is()取括号内最高权重,:where()恒为0-0-0;误用会导致样式静默失效或意外覆盖,且语法容错极低,非法写法会使整条规则被浏览器丢弃。

:where() 和 :is() 唯一实质区别就是权重(specificity)计算方式不同——其他所有行为都一致。 选错一个,样式可能静默失效,或意外覆盖第三方组件。

权重怎么算?:is() 取括号内最高权重,:where() 恒为 0-0-0

:is(.btn, #header, [data-id]) 的权重 = #header 的权重(1-0-0),整条规则能压过大多数类名选择器;

:where(.btn, #header, [data-id]) 的权重 = 0-0-0,哪怕里面塞了 #nav ul li a:hover,它也只靠外部选择器“借权”,比如 nav :where(a) 靠的是 nav 的 0-1-0。

  1. 误用 :where() 写覆盖样式(如 :where(.btn) { color: red; }),连一个普通 div.btn 都压不过——它根本没权参与层叠竞争
  2. :is() 括号里混进 ID 或属性选择器(如 :is(.btn, [data-role="submit"])),权重立刻飙升,可能破坏原有 CSS 层叠顺序
  3. !important:where() 无效:权重为 0 的声明加 !important,仍会被任何非 0 权重规则覆盖

哪些写法会直接让整条规则被浏览器丢弃?

两者语法容错极低,任意一处不合法,整条 CSS 规则都会被静默忽略(控制台常无报错):

  1. 括号内含非法伪类::is(:hover):where(:focus) 不合法;但 :is(button:hover) 合法
  2. 伪元素不支持::is(.a::before):where(.b::after) 直接报错
  3. 逗号/空格错误::is(.a, .b, )(末尾多逗号)、:is(.a,.b)(缺空格)在部分浏览器中失效
  4. Safari ≤15.3 会直接跳过整条 :is() 规则;Safari 15.0–15.3 对 :where() 也有解析 bug

什么时候该用 :where(),而不是 :is()?

:where() 不是“更安全的 :is()”,它是专为“零干扰”设计的:

  1. 全局重置::where(*) { margin: 0; } 不会干扰任何已有规则
  2. 设计系统穿透 scoped style::where(.el-button) { padding: 8px; },避免因权重过高污染子组件
  3. 禁用光标兜底::where(button, input[type="button"], [role="button"]) { cursor: default; },不会压过 button:hover { cursor: pointer; }
  4. 别拿它做增强控制——想统一 hover 态?用 :is();想安全重置?才轮到 :where()

真正容易被忽略的点是:权重变化不可见。你改一个函数名,CSS 就可能在生产环境里悄悄失效或越权覆盖,而开发者工具里看不出任何异常——必须靠 @supports selector(:is(*)) 和实机验证兜底。

热门栏目