:not()只支持单个简单选择器,禁用后代/子代等复合写法;排除多个条件需重复书写如:not(.a):not([b]);与:nth-child混用时仍按原始序号匹配,非过滤后重排。

not伪类怎么写才不会报错
直接写 :not(.header) 没问题,但写成 :not(.header .nav) 就会失效——:not() 里只允许单个简单选择器,不支持后代、子代或复合选择器。
常见错误现象:Uncaught DOMException: Failed to execute 'querySelector' on 'Document' 或样式完全不生效。
- 只能用:类名
:not(.active)、标签名:not(div)、属性选择器:not([disabled])、伪类:not(:hover) - 不能用:空格(后代)
:not(.box .item)、>(子选择器)、逗号分隔多个条件 - 想排除多个类型?得嵌套或重复写:
:not(.skip):not([data-ignore])
排除带特定属性的input元素
比如要给所有非禁用、非只读的 input 加边框,但又不想手动加 class,用 :not() 最直接。
注意 [disabled] 和 :disabled 行为不同:前者匹配 HTML 中写了 disabled 属性的元素(哪怕 JS 动态设了 disabled = false),后者匹配当前实际禁用状态。
立即学习“前端免费学习笔记(深入)”;
- 推荐用伪类判断真实状态:
input:not(:disabled):not(:read-only) - 如果依赖属性存在与否,用属性选择器:
input:not([disabled]):not([readonly]) - 别漏掉 type 类型过滤,比如
input[type="hidden"]通常不该参与样式逻辑,可加:not([type="hidden"])
not和nth-child混用时的陷阱
:not() 本身不影响元素在父容器中的位置计数,但人容易误以为它会“跳过”被排除的元素再算 nth-child。
比如 li:not(.ignore):nth-child(2n) 并不是“排除 .ignore 后重新编号再取偶数位”,而是先按 DOM 顺序取第 2、4、6… 个 li,再从中筛选出非 .ignore 的——结果可能一个都匹配不到。
- 真要按视觉顺序隔行变色,得用
:nth-of-type配合结构优化,或改用 JS 动态加 class - 调试时可用浏览器 DevTools 的 “Force state” 功能单独验证
:not()是否命中 - 复杂逻辑别硬塞进 CSS,尤其涉及动态增删节点时,
:not()+nth-组合极易失控
兼容性与性能要注意什么
:not() 在现代浏览器中基本无压力,但 IE 仅支持到 :not(selector) 单一简单选择器(IE9+),且不支持伪元素如 :not(::before)。
性能上,:not() 本身开销不大,但嵌套过深或搭配低效选择器(如 div *:not(.safe))会显著拖慢渲染。
- 避免在通用祖先选择器后紧跟
:not(),比如body :not(.skip) { ... } - 优先用 class 控制显隐,而不是靠
:not()大范围排除——CSS 规则越具体,重绘成本越可控 - Webpack/Vite 构建时若开启 CSS 压缩,部分工具会错误合并
:not()规则,建议保留空格并加注释说明意图
:not() 就可能从捷径变成盲区。










