:is()权重取内部最高选择器权重,自身不增加权重;如:is(.btn, #submit, p)权重等同于#submit的(0,1,0,0),而非叠加或平均。

:is() 的权重完全不参与计算,只取内部最高权重
浏览器对 :is() 的处理是“透传式”的:它本身不增加任何权重,但会把括号里所有选择器中权重最高的那个直接拎出来,作为整个 :is() 选择器的权重。比如 :is(.btn, #submit, p),实际权重不是叠加,而是取 #submit 的 (0,1,0,0);而 :is(.warning, [data-err]) 权重就是 (0,0,1,0),和单独写 .warning 一样。
常见错误现象::is(.a, .b, .c) 被当成高权重选择器来“防覆盖”,其实毫无意义——它不会比单个 .a 更强;开发者工具里 hover 查看 specificity,显示的值也始终等于内部最高项。
使用场景:
- 需要统一控制多个不同权重的选择器(如同时匹配 class 和 ID 元素)时,用
:is()简化写法,但别指望它提权 - 配合现代 CSS(如
:is(:hover, :focus-visible))做逻辑聚合,语义清晰且无副作用 - 注意 Chrome 100+ / Firefox 95+ 才完全支持嵌套复杂选择器,老版本里
:is(.x .y)可能被忽略
:not() 本身零权重,但内部选择器全量计入
:not() 自身不贡献任何权重,但它括号里的内容——无论多深、多复杂——都会被完整解析并计入总权重。例如 :not(.disabled) 权重是 (0,0,1,0);:not(div#main.active[data-loaded]) 权重是 (0,1,2,1),和写成 div#main.active[data-loaded] 完全一致。
容易踩的坑:
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
-
:not(.a):not(.b)是两个独立的 (0,0,1,0),总权重仍是 (0,0,1,0),不是 (0,0,2,0);它的作用是双重过滤,不是提权 -
:not(:not(.x))是非法语法,现代浏览器直接丢弃整条规则,DevTools 里会灰掉,且无报错提示 - 想排除「带两个类」的元素,必须写
:not(.first.last),而不是:not(.first):not(.last)——后者会把同时含两个类的元素也筛掉
对比 :is() 和 :not() 在复合选择器中的表现
当它们出现在更长的选择器链中时,行为差异立刻暴露。比如:
-
nav :is(.link, .cta)→ 权重 = (0,0,1,0) + (0,0,0,1) = (0,0,1,1) -
nav :not(.disabled)→ 权重 = (0,0,1,0) + (0,0,0,1) = (0,0,1,1) -
nav :is(.link, #primary)→ 权重 = (0,1,0,0) + (0,0,0,1) = (0,1,0,1) -
nav :not(#primary)→ 权重 = (0,1,0,0) + (0,0,0,1) = (0,1,0,1)
关键点在于::is() 和 :not() 都不额外加权,但它们内部的“最强项”决定了上限;而外部选择器(如 nav)的权重是稳定叠加的。所以真正影响层叠结果的,永远是那个“最重的子表达式”。
为什么不能用十进制加法算权重?
因为 (a,b,c,d) 是**逐位比较**,不是数值相加。比如 (0,0,10,0) 和 (0,1,0,0):前者按十进制是 100,后者是 100,看似相等;但实际比较时 b 位 0
这也解释了为什么 :is() 必须取最大值:如果它把所有项都加起来,(0,0,1,0) + (0,0,1,0) = (0,0,2,0),就违背了“ID 永远高于 class”的底层逻辑。浏览器宁可让 :is() 变成“择优录取”,也不让它变成“暴力叠加”。
真正容易被忽略的是:当你在调试样式覆盖问题时,如果看到一条用了 :is() 或 :not() 的规则没生效,第一反应不该是“是不是它权重不够”,而应打开 DevTools 的 Computed 面板,点开该规则,看它实际算出的 specificity 值——那才是它真实的身份。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










