:is()的权重取括号内最高specificity选择器的值,:where()权重恒为0-0-0;前者适合统一增强样式,后者用于零干扰场景如css reset。

:is() 的权重由括号内最高 specificity 的选择器决定
它不是取平均、也不是相加,而是直接继承括号里最强的那个。比如 :is(.btn, #header, [data-id]) 整条规则的权重就是 #header 的 1-0-0,哪怕你只打算给按钮提权,结果却意外覆盖了 ID 级别的样式。
常见错误现象::is(.a, .b, .c) 和单独写 .a 权重完全一样——因为三者都是 0-1-0,没带来任何提升;真正有用的是混用类型,例如 :is(button, [type="submit"], .submit-btn),此时权重由 [type="submit"](0-1-0)或更重的选择器决定。
-
:is()不支持伪元素(如.a::before)和非法伪类(如单独写:hover) - 括号内任意一个选择器语法错误(比如多逗号、空项
:is(.a, )),整条 CSS 规则会被浏览器静默丢弃 - Safari 15.4 之前不支持嵌套
:is(:is()),会直接失效
:where() 的权重恒为 0-0-0,不参与层叠竞争
无论你塞进 #nav .item:hover 还是 *[data-test],整个 :where() 块的权重始终是 0-0-0。它只靠外部选择器“借力”,比如 nav :where(a, button) 的权重只算 nav 那部分(0-1-0)。
典型误用场景:以为 :where() 是“更安全的 :is()”,结果样式压根不生效——因为它连一个普通 div 标签选择器(0-0-1)都压不过。
-
!important对:where()无效:权重为 0 的声明加!important,仍会被任何非 0 权重规则覆盖 - 不能写
:where(a:hover)—— 旧 Safari 可能直接忽略整条规则 - 必须确保外部有足够权重支撑,否则它只是个摆设
什么时候该用 :is(),什么时候该用 :where()
:is() 适合增强已有样式的统一控制,比如给多个容器下的链接加 hover 态::is(header, main, footer) a:hover;或者配合状态类做批量响应::is(.dark, .light) .text。
:where() 是专为“零干扰”设计的,典型用于 CSS Reset、设计系统基底样式、或 <style scoped></style> 中穿透第三方组件::where(.el-button) { padding: 8px 16px; },不会因权重过高破坏子组件原有样式。
- 别在关键路径上全量替换旧写法——比如把所有逗号分组立刻换成
:where(),尤其在 CMS 或嵌套框架里 - 想覆盖别人样式?该用更高 specificity,而不是换伪类
-
@supports selector(:where(*))是渐进增强的必要手段,降级必须手动处理
兼容性与降级必须手动兜底
Chrome 105+、Firefox 103+、Safari 15.4+ 稳定支持两者,但 Edge 17 及更早、所有 IE 版本完全不支持。PostCSS 插件对 :where() 的降级更保守,部分版本会直接剔除而非模拟。
安全做法是用 @supports 显式检测:
@supports selector(:where(*)) {
:where(button, input[type="button"]) {
cursor: default;
}
}
@supports not selector(:where(*)) {
button, input[type="button"] {
cursor: default;
}
}
真正容易被忽略的点在于:权重计算发生在解析阶段,不是运行时;一旦你混入 ID 或属性选择器到 :is() 里,就可能在毫无察觉的情况下打破原有层叠秩序。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











