:is()适合合并重复前缀且需保留高权重的场景,如.card :is(h1, p, .meta)避免重复书写.card,权重取括号内最高值,旧版Safari需降级兼容;:where()则恒为0权重,专用于零干扰重置。

:is() 适合合并重复前缀且需保留高权重的场景
当你反复写同一段祖先路径,比如 .card h1、.card p、.card .meta,用 :is() 提取共用部分最直接:.card :is(h1, p, .meta)。它不是为了“扁平化嵌套”,而是避免改类名时漏掉某一处。
常见错误现象:写成 :is(.card h1, .card p)——语法合法,但失去“父级统一”的语义,后续改 .card 为 .panel 得全文本替换,反而更难维护。
-
:is()内部每个选择器必须是合法简单选择器或组合选择器,不能含伪元素(如h2::after)或孤立伪类(如:hover单独出现) - 权重取括号内最高值:
:is(.foo, #bar) span的权重等同于#bar span(101),不是.foo span(11) - Safari ≤15.3 完全不支持,会静默丢弃整条规则;旧版需搭配
@supports selector(:is(*))做降级
:where() 是零权重兜底的唯一安全解法
想给所有按钮加默认光标,又怕压过用户写的 button:hover { cursor: pointer; }?用 :where()::where(button, [role="button"], .btn) { cursor: default; }。它的权重恒为 0-0-0,无论里面塞了 #nav 还是 div > ul li a,都不会参与层叠竞争。
常见误用:拿 :where() 当“更安全的 :is()”来用——它根本不是用来覆盖样式的,而是用来“不抢权”的。
立即学习“前端免费学习笔记(深入)”;
规划您的迪拜之旅 — 哈利法塔观景、沙漠探险、迪拜购物中心购物、棕榈岛度假村及黄金市场砍价。还提供支持...
-
:where()支持复杂选择器,包括:not()嵌套、属性选择器甚至组合器(如:where(nav > ul, .menu-list) li a) - Safari 15.0–15.3 存在解析 bug,可能跳过整条规则;Chrome 105+/Firefox 103+ 稳定,但上线前仍需检查目标环境
- 别指望
:where()+!important能破局——权重为 0 的声明,加!important仍会被任何非 0 权重规则覆盖
混用时最容易忽略的匹配逻辑陷阱
:where(.dark) :is(h1, h2) 不是“暗色模式下才生效”,而是只要页面里存在 .dark 类(不管是否启用),就会匹配所有 h1 和 h2。因为 :where() 只管匹配,不带条件判断语义。
错误现象:样式在白天也触发,调试时发现控制台没报错,但行为和预期不符——问题出在把 :where() 当 JS 的 if 用了。
-
:is()和:where()都只做静态匹配,不感知 DOM 状态变化或媒体查询 - 真要实现条件逻辑(如暗色模式),得靠
@media (prefers-color-scheme: dark)或 CSS 自定义属性配合:is([data-theme="dark"]) - 构建工具(如
postcss-preset-env)可能默认降级:is()为长逗号列表,体积反而增大,需显式关闭降级配置
语法错误会导致整条规则被浏览器静默丢弃
写了 :is(.btn, .btn-lg, )(末尾多逗号)或 :is(.a, :hover)(孤立伪类),Chrome 和 Firefox 会直接忽略整条 CSS 规则,控制台可能只报模糊警告,样式就没了。
这不是 bug,是规范要求的容错机制——宁可全失效,也不让部分生效引发不可控覆盖。
- 检查三件事:括号是否闭合、逗号是否多余、内部是否含非法选择器(如伪元素、
:is()套:is()) - 旧版 Safari 对
:is()解析有历史 bug,遇到:is(a, b) + c这类相邻兄弟选择器曾直接忽略整条规则(现已修复,但仍建议上线前验证) - IE 和 Edge 17 及更早版本完全不支持,polyfill 无法模拟权重逻辑,必须手动 fallback

















