真正可靠的做法是用JS切换class,CSS响应class:为元素添加is-clicked等类,通过click事件调用classList.add()或toggle()控制样式,因:focus和:target均无法持久记忆点击状态。

点击后样式停留,不能只靠 :focus 或 :target 直接实现——它们触发条件不同,且默认不“记忆”点击状态。
为什么 :focus 通常不满足“点击后停留”需求
元素获得焦点(比如点击 button、input)时,:focus 生效;但鼠标移开或按 Tab 离开后,焦点丢失,样式自动消失。对 div、span 等非可聚焦元素,默认根本不会触发 :focus。
- 要让普通元素响应
:focus,必须加tabindex属性,例如- 即使加了
tabindex,点击后若没主动调用.focus(),部分浏览器(如 Safari)可能不自动聚焦:focus是瞬时状态,不是“已点击过”的记录 —— 它无法区分“刚点一下”和“点完还留着”为什么
:target也不直接等于“点击停留”:target匹配 URL 中#xxx片段标识符所指向的元素(如https://site.com/#section2→#section2元素匹配:target)。它依赖 URL 变化,不是 DOM 状态。- 需要配合带
href="#id"的链接(a标签),点击才会改变 URL 并触发:target - 用户手动改地址栏、前进/后退也会触发,行为不受控
- 单页应用中,如果用 JS 拦截了跳转(如
event.preventDefault()),:target就不会生效 - 不支持伪类链式判断,比如无法写
div:target.active表示“既是 target 又有 active 类”
真正可靠的做法:用 JS 切换 class,CSS 响应 class
把“是否被点击过”这个状态,显式存为 class,是最可控、兼容性最好、语义最清晰的方式。
- 给目标元素加一个可切换的 class,例如
is-clicked或active - 用 JS 绑定
click事件,调用element.classList.toggle('is-clicked') - CSS 中写
.my-btn.is-clicked { background: #007bff; }即可 - 如果只需“点一次就停留”,用
.add('is-clicked')替代toggle - 注意:避免在
label或带for的场景里误触发多次(可加event.stopPropagation())
button { background: #eee; } button.is-active { background: #007bff; color: white; }对应 JS:
document.querySelector('button').addEventListener('click', e => {<br> e.target.classList.add('is-active');<br>});补充:如果坚持纯 CSS,
:focus-within或:has()仍不能替代状态管理:focus-within适用于容器内子元素获得焦点时高亮容器,但焦点一旦离开就失效;:has(:focus)同理,且:has()在 Safari 15.4+ 才稳定支持,旧版不兼容。- 它们都是实时检测,不是状态快照
- 无法实现“点三次变红、再点恢复”的多态逻辑
- 对触摸设备(无 hover/focus 概念)支持弱
真正需要“点击后保留样式”的地方,基本都绕不开 JS 记录状态 —— 这不是妥协,而是 Web 平台的设计事实。
- 即使加了
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











