你是不是经常遇到这样的情况:想给所有按钮加样式,偏偏要排除那个"禁用"状态的;想给列表项加边框,最后一个却要去掉?以前可能要写一堆覆盖样式,现在有了:not()伪类,这些问题都能轻松解决!今天就来聊聊这个被低估的CSS神器,让你的代码更简洁、更优雅。
一、什么是:not()伪类?
简单说,:not()就是排除特定元素的选择器。它能帮你选中"不符合某个条件"的元素,避免写重复的覆盖样式。比如想给所有段落文字变红色,但排除带.special类的段落,用:not()一句话就能搞定:
p:not(.special) {
color: red;
}是不是比先给所有p设红色,再单独给.special重置颜色要清爽多了?
二、基础用法:3分钟上手
1. 基本语法
选择器:not(要排除的条件) {
/* 样式规则 */
}举个栗子:给所有<a>标签加下划线,但排除带[href^="#"]的锚点链接:
a:not([href^="#"]) {
text-decoration: underline;
}2. 支持哪些"排除条件"?
:not()括号里可以放各种简单选择器,比如:
- 类选择器:.class(排除带某个类的元素)
- ID选择器:#id(排除某个ID的元素)
- 属性选择器:[type="text"](排除特定属性的元素)
- 伪类::first-child(排除第一个子元素)
代码示例:排除禁用状态的按钮([disabled]是属性选择器):
button:not([disabled]) {
cursor: pointer; /* 只有非禁用按钮有手型光标 */
}三、实战案例:这些场景用:not()超爽!
1. 列表样式:最后一项不加边框
以前写列表,总要给最后一项单独去掉边框,现在用:not(:last-child)一步到位:
/* 给所有列表项加下边框,除了最后一个 */
li:not(:last-child) {
border-bottom: 1px solid #eee;
}效果:
(图中展示了列表项样式,前三个有下边框,最后一个没有)
2. 表单美化:排除提交按钮
表单里有文本框、单选框、提交按钮,想统一设置输入框样式,但排除提交按钮?:not([type="submit"])轻松实现:
/* 所有输入框加内边距和边框,除了提交按钮 */
input:not([type="submit"]) {
padding: 8px;
border: 1px solid #ddd;
}3. 多条件排除:同时排除多个类
如果要排除多个条件,CSS4支持直接用逗号分隔(现代浏览器已支持):
/* 排除带.active或.disabled类的div */
div:not(.active, .disabled) {
opacity: 0.7;
}如果需要兼容旧浏览器(如IE),可以链式调用:not():
div:not(.active):not(.disabled) {
opacity: 0.7;
}4. 复杂选择器组合:排除嵌套元素
:not()还能和其他选择器组合,比如排除<pre>标签内的<code>(避免代码块样式冲突):
/* 给所有<code>加背景,除了<pre>里的 */
code:not(pre code) {
background: #f5f5f5;
padding: 2px 4px;
border-radius: 4px;
}代码与效果对比:
(左侧为代码编辑区域,右侧为运行效果,内联代码有灰色背景,代码块无背景)
四、避坑指南:这些错误别踩!
1. 优先级陷阱
:not()本身没有优先级,优先级由括号里的条件决定。比如:
/* 优先级 = div(0,0,1) + .class(0,1,0) = 0,1,1 */
div:not(.class) {
color: red;
}如果后面有.class选择器,可能会被覆盖,记得计算优先级哦!
2. 逻辑搞反:"或"和"与"的区别
用逗号分隔多个条件时,是"排除满足任意一个条件"(或关系),而链式:not()是"排除同时满足所有条件"(与关系):
/* 错误:排除.active或.disabled,结果所有元素都被选中(因为元素不可能同时是.active和.disabled) */
input:not(.active), input:not(.disabled) { ... }
/* 正确:排除同时是.active和.disabled的元素(实际很少见,一般用逗号分隔) */
input:not(.active):not(.disabled) { ... }3. 别用复杂选择器(CSS3限制)
CSS3中,:not()括号里不能用组合选择器(比如div p、a > span),但CSS4支持。如果需要兼容旧浏览器,避免这样写:
/* CSS3不支持,会失效! */
:not(div > p) { ... }五、高级技巧:和这些选择器搭配更强大
1. 与:nth-child组合:排除特定位置元素
比如给列表项加右边距,除了第2个和第4个:
li:not(:nth-child(2)):not(:nth-child(4)) {
margin-right: 10px;
}2. 在Tailwind中使用
Tailwind也支持:not(),比如给所有按钮加 padding,排除.small类:
<button class="px-4 py-2 bg-blue-500 text-white">正常按钮</button>
<button class="px-4 py-2 bg-blue-500 text-white not(.small)">排除小按钮</button>3. 简化重置样式
以前重置样式可能要写一堆类,现在用:not()一句话覆盖:
/* 所有元素默认隐藏,除了.active的面板 */
.panel:not(.active) {
display: none;
}六、浏览器兼容性
- 现代浏览器(Chrome 88+、Firefox 78+、Safari 14+):支持CSS4语法,可逗号分隔多个条件(如:not(.a, .b))。
- 旧浏览器(IE9+):仅支持单个条件,需用链式:not()(如:not(.a):not(.b))。
可以用Can I use查询具体兼容性。
总结:为什么要用:not()?
- 少写覆盖样式:不用先设置所有元素,再单独重置例外。
- 代码更简洁:逻辑清晰,一眼看出排除条件。
- 灵活度高:支持多种选择器组合,适配复杂场景。
下次写CSS时,别再堆覆盖样式了,试试:not()伪类,让代码更优雅!你用过:not()吗?欢迎在评论区分享你的技巧~
(注:文中部分代码示例参考自MDN和CSS-Tricks)
