:not(.a, .b) 静默失效,因 css selectors level 3 规定 :not() 仅支持单个简单选择器;正确写法是 :not(.a):not(.b),兼容性好且逻辑为 and。

为什么 :not(.a, .b) 会静默失效
浏览器遇到这种写法会直接丢弃整条 CSS 规则,不报错、不警告、也不生效——因为 CSS Selectors Level 3 明确规定::not() 的参数只能是「单个简单选择器」。.a, .b 是两个选择器用逗号分隔,语法非法。Chrome、Firefox、Safari(截至 2026 年 10 月)均不支持该写法,Safari 尤其严格。
正确写法是链式连写 :not(.a):not(.b)
这是目前最兼容、最可靠的方式,等价于“既不匹配 .a,也不匹配 .b”:
-
div:not(.disabled):not(.hidden) { opacity: 1; }→ 只作用于既没disabled类、也没hidden类的div - 顺序无关:
:not(.b):not(.a)效果完全一致 - 如果某个元素同时有
.disabled和.hidden,它仍被排除——这符合逻辑 AND,不是 bug - 特异性(specificity)不变:权重仍是外部选择器 + 每个
:not()内部选择器之和,不会因多写一层而“变强”
属性选择器也能用于多条件排除,但注意匹配精度
想排除带特定属性值的元素,:not([attr="value"]) 完全合法,且比类名更精确:
-
input:not([type="hidden"]):not([type="file"]) { padding: 8px; }→ 排除两种 type -
[data-status]:not([data-status="draft"]):not([data-status="archived"]) { color: #333; }→ 先确保有data-status属性,再排除具体值 - 注意:
:not([hidden])排除所有含hidden属性的元素(无论值为何),而:not([hidden=""])只排除显式写成hidden=""的
容易忽略的关键点:它不看祖先,也不处理动态上下文
:not() 只检查目标元素自身是否匹配括号内的条件,对父级、兄弟、或运行时状态无感知:
-
.card p:not(.meta)不会跳过.card--compact .meta里的p——只要那个p自身没.meta类,就会命中 -
button:not(.primary):not(.secondary)对 JS 动态添加的类无效,除非样式重新计算(如 classList 切换后重排) - Tailwind 响应式类如
md:hidden可以照常用于:not(),但媒体查询生效与否取决于当前视口,:not()不会“跨断点反转”逻辑
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











