:not() 在 IE 全系列、Safari ≤15.4、Chrome ≤38 中不支持,IE 完全不识别该伪类,旧版 WebKit 和 Blink 引擎会整条规则静默丢弃,且 @supports selector(:not(*)) 检测不可靠。

:not() 在 IE 全系列、Safari ≤15.4、Chrome
为什么 :not() 在老浏览器里“消失”了?
IE6–IE11 完全不支持 :not(),连最简单的 div:not(.active) 都会被跳过;Safari ≤15.4 遇到多参数写法 :not(.a, .b) 会标记为 “Invalid CSS” 并整条忽略;Chrome 73 以前也不认多参数形式。这些都不是报错,而是静默丢弃——你在 DevTools 里看到的是一条被划掉的规则,不是没匹配上,是根本没进解析器。
-
:not()没有历史厂商前缀(比如-webkit-not),autoprefixer 对它完全无能为力 - 链式写法
:not(.a):not(.b)的逻辑是“且”,不是“或”,但兼容性反而更好 - 伪类顺序不影响结果,但
:not()放在前面(如a:not(.external):hover)更易读、也更稳
怎么把 :not(.a, .b) 安全降级?
别试图用 PostCSS 自动转译——postcss-preset-env 默认不展开多参数 :not(),必须显式配 notParens: true 才行,而很多构建链路根本没开这个开关。
- ✅ 正确做法:手动手动拆成链式
:not(.a):not(.b),所有主流浏览器(包括 IE8+ 的部分 polyfill 环境)都认 - ❌ 错误做法:保留
:not(.a, .b)并指望构建工具兜底,Safari ≤15.4 下页面就少样式 - ⚠️ 注意:
:not(.a.b)(同时含两个类)虽是 Level 4 合法语法,但 Safari ≤15.4 仍静默忽略,不要用
IE8 及以下彻底不支持时,怎么绕开 :not()?
当目标必须兼容 IE8 或更低版本,:not() 就得整个移除,不能降级,只能重构逻辑。
立即学习“前端免费学习笔记(深入)”;
- 用显式 class 列举替代:把
input:not([type="hidden"])拆成input[type="text"], input[type="email"], input[type="password"] - 用修饰符反转逻辑:把
.card:not(.card--disabled) .card__button拆成两条:.card .card__button+.card--disabled .card__button { display: none; } - 避免 JS 动态加 class 做兜底——DOM 变更后 Selectivizr 等 polyfill 不会重匹配,容易漏样式
构建和调试时最容易忽略的点
真正踩坑的往往不是写法本身,而是验证盲区:
- Safari 开发者工具里看样式是否被划掉,比“元素没变色”更能早发现问题
- 条件注释(如
<!--[if lt IE 9]>)只对 HTML 有效,不能塞进 CSS 文件里 hack:not() - SCSS 中用
&:not(...)编译后若生成了:not(),就得检查输出 CSS 是否真被处理了,别信源码看着“高级”就以为安全


















