
本文介绍一种纯 html/css 的巧妙方案,通过嵌套可聚焦元素与 pointer-events 切换,实现在两次点击后将鼠标指针变为 not-allowed,无需任何 javascript。
本文介绍一种纯 html/css 的巧妙方案,通过嵌套可聚焦元素与 pointer-events 切换,实现在两次点击后将鼠标指针变为 not-allowed,无需任何 javascript。
在标准 CSS 中,:active 伪类仅响应当前按下状态,而 :focus 只能捕获单次获得焦点事件——因此单纯依赖单一伪类无法区分“第几次点击”。但我们可以利用浏览器对 tabindex 元素的焦点管理机制和 pointer-events 的级联特性,构建一个两阶段交互流程:
✅ 实现原理
- 外层容器(如
#slide-arrow-prev)设为可聚焦(tabindex="0"),首次点击时获得焦点 → 触发:focus,但此时光标不变更; - 内层子元素(如
#inner)同样可聚焦,且初始具备鼠标响应(pointer-events: auto); -
第一次点击:焦点落在内层元素上 → 其
:focus触发,立即设置pointer-events: none,使其失去后续点击能力; -
第二次点击:因内层已禁用指针事件,点击穿透至外层容器 → 外层获得焦点 → 触发
#slide-arrow-prev:focus→ 光标变为not-allowed。
? 完整示例代码
<div tabindex="0" id="slide-arrow-prev"> <div tabindex="0" id="inner">Click Me</div> </div>
#slide-arrow-prev {
height: 50px;
width: 80px;
background: lavender;
outline: none; /* 可选:移除默认焦点轮廓 */
}
#inner {
height: 100%;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
}
/* 第二次点击后:外层获得焦点 → 光标禁用 */
#slide-arrow-prev:focus {
cursor: not-allowed;
}
/* 第一次点击后:内层失焦并禁用指针事件 */
#inner:focus {
pointer-events: none;
}⚠️ 注意事项
- 必须为两个元素都设置
tabindex(推荐"0"),否则无法触发:focus; - 确保外层无
pointer-events: none,否则点击无法传递焦点; - 若页面有其他焦点操作(如 Tab 键导航),可能干扰该逻辑,建议配合
outline: none并提供无障碍替代方案(如 ARIA 标签); - 此方案依赖用户主动点击可聚焦区域,不适用于纯悬停(
:hover)场景。
? 总结
虽然 CSS 本身不具备计数能力,但通过组合 :focus、pointer-events 与 DOM 层级穿透行为,我们成功模拟了“双击状态切换”的效果。这体现了 CSS 在有限约束下实现复杂交互的潜力——当然,生产环境中仍推荐 JS 实现更可靠、可维护的状态管理;而本方案更适合教学演示或轻量级原型验证。



















