
通过 CSS 的 body:not(:hover) 伪类配合 JavaScript 动态定位,可实现在鼠标离开视口时自动隐藏自定义圆形光标,避免其滞留在屏幕边缘。
通过 css 的 `body:not(:hover)` 伪类配合 javascript 动态定位,可实现在鼠标离开视口时自动隐藏自定义圆形光标,避免其滞留在屏幕边缘。
要让自定义圆形光标(.cursor)在用户将鼠标移出浏览器窗口(即页面区域)时自动隐藏,最简洁、高效且无需额外 JavaScript 监听 mouseout 或 mouseleave 事件的方法是利用 CSS 的 :hover 伪类与 :not() 组合选择器。
✅ 核心原理
body:hover 表示鼠标当前位于
元素内部(即页面可视区域内)。反之,body:not(:hover) 则精准匹配鼠标完全离开整个文档视口的状态(包括滚动条、地址栏上方等非内容区),此时隐藏光标即可达成需求。✅ 推荐实现(精简可靠)
JavaScript 部分(仅需更新位置):
const cursor = document.querySelector('.cursor');
window.addEventListener('mousemove', (e) => {
const { clientX, clientY } = e;
// 使用 translate3d 提升渲染性能,且无需手动处理 scroll offset
cursor.style.transform = `translate3d(${clientX}px, ${clientY}px, 0)`;
});
⚠️ 注意:clientX/clientY 基于视口左上角,天然适配固定定位(position: fixed),比 pageX/pageY - scrollX/Y 更简洁、无滚动偏移风险。
CSS 部分(关键隐藏逻辑):
body {
cursor: none;
margin: 0;
min-height: 100dvh; /* 推荐使用 dvh 单位,更准确适配移动设备 */
}
/* 当鼠标不在 body 上时(即离开页面),隐藏光标 */
body:not(:hover) .cursor {
display: none;
}
.cursor {
position: fixed;
width: 40px;
height: 40px;
border-radius: 50%;
margin: -20px 0 0 -20px; /* 精确居中:负 margin = -width/2, -height/2 */
pointer-events: none;
background: #f0efe9;
mix-blend-mode: difference;
transition: width 0.1s linear, height 0.1s linear;
}
✅ 补充说明与最佳实践
为什么不用 mouseleave 监听 document?
document.addEventListener('mouseleave', ...) 在跨 iframe 或快速移出窗口时行为不稳定;而 body:not(:hover) 是原生 CSS 行为,零延迟、零兼容性问题,且自动响应所有退出场景(含 Alt+Tab 切换、F11 全屏退出等)。关于 mix-blend-mode: difference:
该属性依赖背景色对比度,若页面存在动态主题切换,请确保 .cursor 背色与主背景有足够反差,否则可能不可见。-
移动端适配提示:
此方案默认不适用于触摸设备(无 hover 概念)。如需支持,可结合 @media (hover: hover) 媒体查询做条件启用:@media (hover: hover) { body:not(:hover) .cursor { display: none; } }
综上,仅需三行核心 CSS + 一行优化 JS,即可优雅解决“光标滞留页面外”的问题——简洁、高性能、跨浏览器兼容,是现代自定义光标交互的标准实践。










