:is()取括号内最高specificity子选择器的权重参与层叠,:where()恒为0-0-0不参与竞争;前者适合提权统一控制,后者专用于零干扰重置,语法错误均导致整条规则静默失效。

区别只在权重计算逻辑——:is()取括号内最高 specificity 的子选择器参与层叠,:where()恒为 0-0-0,不参与竞争。其他所有差异(语法、嵌套、错误处理)都只是这个核心区别的副产品。
权重怎么算?一个数字就分胜负
:is()不是加总、也不是平均,是“取最大值”:括号里哪个子选择器权重最高,整条规则就按它算。比如 :is(.btn, #header, [data-id]) 权重就是 #header 的 1-0-0;而 :is(.a, .b, .c) 权重仍是 0-1-0,和单写 .a 一样,毫无提权效果。
:where()不管里面塞了 #nav 还是 div ul li a,整条规则权重永远是 0-0-0。它必须靠外部选择器“借力”,比如 nav :where(a, button) 的权重只算 nav 那部分(0-1-0)。
-
:where(.btn, #primary)看似想兜底+提权,实际权重为 0,连button标签选择器(0-0-1)都压不过 -
:is(.btn, #primary)权重直接按#primary(0-1-0)算,可能意外覆盖.modal .btn -
!important对:where()无效:权重为 0 的声明加!important,仍会被任何非 0 权重规则覆盖
哪些写法会静默失效?浏览器不报错也不生效
两者对语法错误都极其敏感,任意一个子选择器出错,整条 CSS 规则被丢弃——不是忽略错误项,而是整条作废。
立即学习“前端免费学习笔记(深入)”;
- 伪元素非法:
:is(.a::before)、:where(.b::after)直接失效 - 孤立伪类不支持:
:is(:hover)或:where(:focus)单独出现失败,必须绑定到元素(如a:hover) - 空项或多余逗号:
:is(.a, , .b)或:where(.x,)会被忽略 - Safari 15.4 之前不支持嵌套:
:is(:is(.a, .b))不会降级,而是整条失效
什么时候该用 :is(),什么时候必须换 :where()?
选哪个不看“新不新”,只看你是否需要参与权重竞争。
-
:is()适合你本就打算提高权重的场景:比如统一控制多个容器下的链接 hover 态 ——:is(header, main, footer) a:hover,自然获得 0-1-0 权重 -
:where()只适合“加样式但绝不抢权”的场景:比如重置第三方按钮边框、禁用某类元素光标 ——:where(button, input[type="button"]) { cursor: default; },不会压过已有的button:hover { cursor: pointer; } - 别在
:where()里塞 ID 或高权重选择器——它不会提升效果,只会制造误解;也别指望它“安全降权”,它根本没权可降
最容易被忽略的是:权重逻辑不可逆,改函数名不等于改行为;:where() 不是“更安全的 :is()”,它是“完全无权的兜底工具”。一旦你依赖它去覆盖别人样式,大概率会发现它根本没生效。


















