当前位置: 首页 > news >正文

一文吃透 CSS 伪类:从「鼠标悬停」到「斑马纹表格」的 30 个实战场景

0. 前言:为什么你总在写「多余」的 JS?

前端日常中,我们经常会写这样的代码:

// 给每行表格隔行变色
trs.forEach((tr, i) => tr.style.background = i % 2 ? '#fff' : '#f7f7f7');// 给按钮换色
btn.addEventListener('mouseenter', () => btn.style.background = '#eee');
btn.addEventListener('mouseleave', () => btn.style.background = '#fff');

伪类(Pseudo-class) 的存在,就是为了让浏览器帮你干这些「体力活」——一行 CSS 顶替十几行 JS,性能更好、可维护性更高,还能天然支持「未来新增的元素」。


1. 伪类到底是什么?

W3C 原话:

A pseudo-class is a keyword that specifies a special state of the selected element(s).

关键词:状态
伪类并不对应 HTML 中的真实 class,而是描述元素处于某种瞬时或结构上的状态时该如何渲染。
语法:在选择器后加 : + 关键字,如 a:hoverli:nth-child(2n+1)


2. 伪类全家福(CSS Selectors Level 4 版)

类别常用伪类一句话记忆
用户行为:hover :active :focus :focus-visible悬停 / 按下 / 聚焦 / 键盘聚焦
表单反馈:checked :disabled :valid :invalid :in-range :out-of-range勾、禁、对、错、范围内、超范围
结构 / 序号:first-child :last-child :nth-child() :nth-of-type() :only-child第 n 个、倒数第 n 个、同类第 n 个
超链接历史:link :visited未访问 / 已访问
其他:target :root :empty :not()锚点、根节点、空节点、反选

3. 实战:不用伪类 vs 用伪类

3.1 隔行变色(斑马纹)

/* ==== 1 行 CSS ==== */
.striped-table tbody tr:nth-child(2n) { background:#f7f7f7; }

不用伪类:

// 还要考虑动态新增、排序、翻页……
document.querySelectorAll('tbody tr').forEach((tr,i)=>{tr.style.background = i%2 ? '#f7f7f7' : '';
});

3.2 自定义复选框

/* 隐藏原生框,用兄弟元素画钩 */
input[type=checkbox] { display:none; }
input[type=checkbox] + label::before {content:'';display:inline-block;width:14px; height:14px;border:1px solid #999;margin-right:6px;
}
input[type=checkbox]:checked + label::before {background:#1890ff url(tick.svg) center/10px no-repeat;
}

不用伪类: 得监听 change 事件,手动增删 class。

3.3 聚焦输入框高亮

.form-input:focus { border-color:#1890ff; box-shadow:0 0 0 2px rgba(24,144,255,.2); }

不用伪类:onfocus/onblur 来回改行内样式。

3.4 数字输入框范围提示

input[type=number]:in-range  { border-color:#52c41a; }
input[type=number]:out-of-range { border-color:#ff4d4f; }

不用伪类:oninput 时读 value 再比大小。

3.5 空购物车提示

.cart ul:empty::after { content:'购物车是空的,快去逛逛吧!'; color:#999; }

不用伪类: 得 JS 数 li 个数再插入/移除提示节点。

3.6 锚点定位高亮

section:target { scroll-margin-top:80px; background:#fffbe6; }

点击目录跳转时,目标章节自动黄条高亮,无需任何脚本。

3.7 反选过滤

button:not([disabled]) { cursor:pointer; }
/* 只给「可用」按钮加手型,禁用按钮忽略 */

4. 容易踩的坑

  1. 序号伪类是对所有兄弟节点计数,而不是「同类名」。
    ul li:nth-of-type(2n) /* 同类标签第 n 个,不受其他元素干扰 */
    
  2. :hover 在触屏设备上可能「粘滞」,要加 @media(hover:hover) 做区分。
  3. :visited 为了隐私,能改的属性极少(color/border-color/background-color 且透明度必须为 1)。
  4. :focus:focus-visible 区别:后者只在「键盘tab」时出现,鼠标点击不显示,适合做「蓝框」。

5. 性能 & 可维护性

  • 浏览器内部对伪类做了高度优化,比手动 DOM 遍历快得多。
  • 样式与行为分离,产品要改「斑马色」设计师直接改 CSS,无需打扰 FE 重构。
  • 动态内容(ajax 翻页、拖拽排序)也不用重新执行染色脚本。

6. 彩蛋:纯 CSS Toggle 开关

.toggle { display:none; }
.toggle + label { position:relative; width:40px; height:20px;background:#ccc; border-radius:10px; cursor:pointer; }
.toggle + label::after { content:''; position:absolute; left:2px; top:2px;width:16px; height:16px; background:#fff; border-radius:50%; transition:.3s; }
.toggle:checked + label { background:#1890ff; }
.toggle:checked + label::after { transform:translateX(20px); }
<input class="toggle" id="t" type="checkbox"><label for="t"></label>

零 JS 即可得到 Material 风格滑动开关。


7. 速查海报(保存即可)

场景一行代码
隔行变色tr:nth-child(2n){background:#f7f7f7}
首项不同li:first-child{font-weight:bold}
末项补灰线li:last-child{border-bottom:none}
仅一项时隐藏「删除」按钮ul li:only-child .del{display:none}
输入非法红框input:invalid{border-color:#ff4d4f}
鼠标悬停放大img:hover{transform:scale(1.1)}
键盘聚焦蓝环button:focus-visible{outline:2px solid #1890ff}

8. 结语:把 JS 留給业务,把状态交給 CSS

伪类不是「小语法糖」,而是声明式编程在前端的最好体现。
下次接到「奇偶行变色」「按钮按下换色」「表单验证红框」等需求,先想想:
能不能一行伪类解决?
能,你就省下:

  • 至少 10 行 JS
  • 一次 DOM 查询
  • 未来维护时踩坑的风险

把省下的时间用来写业务逻辑,或摸鱼,也是极好的。


9. 参考资料 & 延伸阅读

  • CSS Selectors Level 4 – W3C
  • MDN :nth-child 可视化工具
  • Can I use – 查询兼容性
  • 《CSS 揭秘》Chapter 3「结构布局」

(完)

http://www.dtcms.com/a/366754.html

相关文章:

  • 中值滤波、方框滤波、高斯滤波、均值滤波、膨胀、腐蚀、开运算、闭运算
  • HTML图片标签及路径详解
  • Python开篇撬动未来的万能钥匙 从入门到架构的全链路指南
  • 工厂模式总结
  • C++知识
  • C 盘清理技巧分享:释放磁盘空间,提升系统性能
  • 将 PDF 转换为 TIFF 图片:简单有效的 Java 教程
  • 数据传输,数据解析与写数据库
  • django全国小米su7的行情查询系统(代码+数据库+LW)
  • 阿瓦隆 A15 Pro 221TH/S:SHA-256 算力与高效能耗
  • 大模型部署全攻略:Docker+FastAPI+Nginx搭建高可用AI服务
  • Linux 编译 Android 版 QGroundControl 软件并运行到手机上
  • 一天涨幅2000倍的期权有吗?
  • (JVM)四种垃圾回收算法
  • ArcGIS学习-15 实战-建设用地适宜性评价
  • Node.js轻松生成动态二维码
  • Windows+Docker一键部署CozeStudio私有化,保姆级
  • 【Docker】P1 前言:容器化技术发展之路
  • LangChain4J-(4)-多模态视觉理解
  • 少儿编程C++快速教程之——2. 字符串处理
  • SMARTGRAPHQA —— 基于多模态大模型的PDF 转 Markdown方法和基于大模型格式校正方法
  • Unity之安装教学
  • GcWord V8.2 新版本:TOA/TA字段增强、模板标签管理与PDF导出优化
  • 无需任何软件禁用 10 年 windows 更新
  • ArcGIS答疑-如何消除两张栅格图片中间的黑缝
  • 《D (R,O) Grasp:跨机械手灵巧抓取的机器人 - 物体交互统一表示》论文解读
  • 零售消费企业的数字化增长实践,2025新版下载
  • 三目摄像头 是一种配备三个独立摄像头模块的视觉系统
  • 苍穹外卖Day9 | 用户端、管理端接口功能开发、百度地图解析配送范围
  • 算法之二叉树