在编写样式表时,我们经常遇到这样的需求:给某一类元素统一样式,但要把其中少数几个例外排除掉。CSS提供的:not伪类就是专门用来做这种反向匹配的。它接受一个简单选择器作为参数,然后选中所有不满足该条件的元素。把:not和普通选择器组合,能够用很少的代码完成精准过滤,而不必给例外元素额外写覆盖规则。

从底层规范来看,:not属于否定伪类,在选择器优先级计算中,它自身不增加权重,其权重完全由括号里的选择器决定。例如ul li:not(.disabled)的优先级等于一个类选择器加两个类型选择器,而不是额外多出一截。这一点和很多初学者的直觉不同,有人以为用了:not就会让规则变得更强势,其实只是把匹配条件反转了而已。
在参数边界上,CSS Level 3规定:not只能放入简单选择器,包括类型选择器、类选择器、ID选择器、属性选择器以及像:hover这样的简单伪类,但不能放复合选择器或选择器列表(直到Level 4才允许逗号分隔的列表,但浏览器支持仍参差)。所以a:not(.btn, .link)在新版浏览器可用,旧环境会整条规则失效。写代码时要先确认目标用户使用的渲染引擎。
常见组合写法与代码示例
最实用的组合莫过于类选择器加:not。比如导航里除了当前页,其他链接都去掉下划线,可以写成下面这样。这种写法比给每个非当前项单独加类更易于维护,因为当状态变化时,只需要切换.active类即可,样式逻辑不用动。
/* 除激活项外,所有导航链接取消下划线 */
nav a:not(.active) {
text-decoration: none;
color: #555;
}
/* 表单中排除禁用控件,正常控件加边框 */
input:not([disabled]) {
border: 1px solid #ccc;
padding: 4px 6px;
}
属性选择器与:not的组合在表单场景非常频繁。上面的代码展示了如何用[disabled]属性反向过滤,让禁用输入框不显示边框,避免视觉干扰。类似的,还可以用:not([type="hidden"])来排除隐藏域,防止它们意外占据布局空间。
结构伪类也能进入:not内部。比如列表里除了第一项,其余都加上上边框分割线。注意这里用的是:first-child这种简单伪类,完全合规。如果把:not(:nth-child(2n))用于隔行控制,也能轻松实现奇数行高亮而偶数行不变,比写两个互相覆盖的规则清晰得多。
组合使用时的优先级与覆盖陷阱
当多条带:not的规则同时命中一个元素,权重比较只看括号内选择器。例如div:not(.x)和.box冲突时,后者权重更高,因为类选择器胜过多出来的类型选择器。这容易导致开发者以为:not写了就能稳赢,结果被后面普通类规则覆盖,样式没生效却找不到原因。
.box { color: red; }
div:not(.x) { color: blue; }
/* 若元素为 <div class="box">,最终颜色是 red,因为 .box 权重更高 */
另一个陷阱是多层否定展开。有些人写:not(.a):not(.b)想表达既不是a也不是b,这是合法的,且等价于:not(.a, .b)在新标准下。但在不支持列表的旧浏览器,只能链式写多个:not。链式时每个括号独立计算权重,两个类否定叠加后权重等于两个类,仍可能被单类加ID的规则击败。
还要注意:not不能嵌套自身,比如:not(:not(.a))虽在语法上某些引擎不报错,但可读性极差且标准不明确,应当避免。真要做复杂排除,建议把条件拆成独立类或在JavaScript里计算class,不要全压在CSS选择器上。
实战场景与性能考量
在后台管理系统的表格中,常需要给除操作列外的单元格统一对齐。用td:not(.op)就能精准控制,而不必给操作列写重置样式。这种写法减少了冗余规则,也降低了后续改版时漏改的风险。配合[data-role]属性,还能按业务角色过滤显示样式。
<table>
<tr>
<td>名称</td>
<td class="op"><a href="#">编辑</a></td>
</tr>
</table>
从性能角度,浏览器匹配:not时依旧是从右向左解析。括号内若是属性选择器,在超大DOM树下会比纯类选择器稍慢,但现代引擎优化很好,日常千节点规模无感知。真正要避的开销是过度嵌套,如div > ul li:not(.x) a这类长串,应简化为给父级加类后再用:not收缩。
总结来说,:not伪类与CSS选择器组合是一门平衡艺术。弄清简单选择器边界、权重等价规则和浏览器兼容面,才能在精准过滤的同时不让样式表变成陷阱库。多用单类否定、少写复合否定,遇到复杂条件及时上JavaScript辅助,是稳妥的工程做法。
css_selector:not_pseudo_classelement_filtering修改时间:2026-08-15 03:54:30