:hover、:checked、:target、:active、:focus 五个伪类可在简单交互中替代javascript,但需注意可访问性、设备兼容性及边界限制。

:hover、:checked、:target、:active、:focus 这五个伪类在多数简单交互场景中能直接替代JavaScript,不需要监听事件、更新状态或操作DOM。
:hover 和 :focus 适合悬停与焦点交互
鼠标悬停菜单展开、输入框聚焦高亮、按钮按压反馈,都靠这两个伪类就能完成。关键不是“能不能”,而是是否需要支持键盘导航——只用 :hover 会忽略键盘用户,必须搭配 :focus 或 :focus-within 才算可访问。
-
:hover在触摸设备上行为不一致(iOS Safari 只触发一次),别单独依赖它做核心功能 -
:focus默认样式可能被重置,记得保留outline或提供等效视觉反馈 - 下拉菜单推荐用
:focus-within包裹父容器,比监听子元素:focus更可靠
:checked 是表单控件状态同步的最简解法
复选框、单选按钮、开关(toggle)的视觉状态切换,:checked 配合兄弟选择器(+ 或 ~)就能驱动样式变化,完全绕过 change 事件监听。
- 必须确保
<input>在 DOM 中紧邻要控制的元素,否则+无法命中;用~可跨多个同级元素,但仅限后续兄弟 -
:checked不触发重排,性能远优于 JS 切换 class;但无法读取当前值,也不能用于异步校验 - 移动端点击区域小?给
label加padding,别只靠input自身尺寸
:target 实现无 JS 的锚点联动与模态框
URL 中的 #id 变化会自动激活对应元素的 :target 状态,适合标签页切换、FAQ 折叠、轻量级弹窗。
- 模态框需配合
display: none+:target切换display: block,但注意:关闭只能靠跳转到其他#或页面刷新 -
:target不会响应 history.pushState(),JS 修改 hash 后伪类仍会生效,但 popstate 不触发重绘 - SEO 友好——搜索引擎能抓取所有
#对应内容,不像 JS 渲染的内容可能漏掉
:active 和 :empty 解决点击反馈与空状态
:active 天然匹配按下瞬间,:empty 能识别内容为空的容器——这两个伪类常被忽略,但能省掉大量判断逻辑。
-
:active持续时间极短,不适合做持久状态;想上报点击数据?用:active::after { content: url(/log?btn=submit); }即可 -
:empty不匹配含空白符的元素,<div> </div>不算空;预处理时用trim()或服务端清除空格 -
:empty无法区分“数据未加载”和“数据为空”,需配合骨架屏或 loading 类做分层处理
真正难的是边界情况:比如需要延迟隐藏、依赖异步结果、或跨组件通信。这时候伪类就到头了,硬套只会让 CSS 变成状态机模拟器——该写 JS 的地方,别省那几行代码。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











