You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

CSS自定义光标:鼠标左移hover元素闪烁、右移正常的问题排查与解决

问题原因分析

这个闪烁问题的核心是自定义光标元素#circle拦截了鼠标事件,导致hover状态反复切换:

  • 你的#circleposition: fixedz-index: 5,层级比.box高;同时你把它的左上角直接定位在鼠标坐标(clientX, clientY)上,这意味着鼠标指针刚好落在#circle的左边缘区域。
  • 当鼠标从左向右移动进入.box时,刚触发.box:hover的瞬间,#circle的样式发生变化,但此时鼠标实际上是悬停在#circle上(因为它层级更高),这会立刻让.box的hover状态失效——#circle变回原样式,鼠标又重新落在.box上,再次触发hover,如此循环往复,就出现了闪烁。
  • 而从右向左移动时,鼠标指针是从.box的右侧进入,此时#circle的位置在鼠标的左侧(因为left设为clientX),不会挡住鼠标和.box的接触,所以hover状态能稳定保持,不会闪烁。
修复方案

最简单且有效的修复是给#circle添加pointer-events: none;属性,让它完全不接收任何鼠标事件——这样鼠标的hover事件只会作用在下方的.box元素上,不会被自定义光标干扰。

修改后的CSS代码如下:

#circle {
  position: fixed;
  border-radius: 50%;
  z-index: 5;
  height: 32px;
  width: 32px;
  background-color: white;
  pointer-events: none; /* 新增这一行 */
}

另外,如果你想让自定义光标完全对齐鼠标中心(视觉上更自然),可以调整定位方式,把鼠标坐标减去元素宽高的一半:

function cursorMove(ev) {
  let circle = document.getElementById('circle');
  let posY = ev.clientY - circle.offsetHeight / 2;
  let posX = ev.clientX - circle.offsetWidth / 2;
  circle.style.top = posY + 'px';
  circle.style.left = posX + 'px';
}

这个调整不是必须的,但能让光标跟随更贴合鼠标指针的视觉位置,体验更好。


内容的提问来源于stack exchange,提问作者li_

火山引擎 最新活动