光斑扫过效果的核心原理是用::before或::after伪元素模拟高亮椭圆,通过transform: translate()和scale()配合transition实现平滑动画;关键在于transform-origin与translate组合制造视觉错觉,而非真实追踪鼠标。

光斑扫过效果的核心原理是什么
这个效果本质是用 ::before 或 ::after 伪元素模拟一个高亮椭圆,通过 transform: translate() 和 scale() 让它随鼠标位置动态偏移并缩放,再配合 transition 实现平滑过渡。关键不在“追踪鼠标”,而在于让伪元素的位移值看起来像被鼠标“带动”——实际是靠 CSS 的 transform-origin + translate() 组合制造视觉错觉。
常见错误现象:::before 死活不显示、光斑卡在左上角、悬停后光斑不动、移动端失效。
- 必须给宿主元素设
position: relative,否则::before的position: absolute会相对于 body 定位 - 伪元素默认不占文档流,
content: ""是强制声明,缺了就啥也不渲染 -
transform-origin建议设为center,否则缩放+位移容易偏移预期中心 - 不要用
left/top控制位置——要用transform: translate(),否则无法触发硬件加速,动画卡顿
如何用 :hover + ::before 实现基础扫过动画
下面是最小可行代码,适用于按钮、卡片等块级元素:
.spotlight {
position: relative;
overflow: hidden;
}
.spotlight::before {
content: "";
position: absolute;
width: 200%;
height: 200%;
background: radial-gradient(circle, rgba(255,255,255,0.4) 0%, transparent 70%);
transform: translate(-50%, -50%) scale(0);
transition: transform 0.5s ease-out;
z-index: 1;
}
.spotlight:hover::before {
transform: translate(-50%, -50%) scale(1);
}
说明:width/height 设为 200% 是为了确保光斑在任意方向都能完整覆盖;scale(0) 到 scale(1) 配合 translate(-50%, -50%),让光斑从中心扩散而非从左上角展开。
注意:这个版本是「中心爆发式」,不是「跟随式」。若要真正跟随鼠标,需 JS 配合监听 mousemove 并设置 --x/--y CSS 变量——纯 CSS 无法读取鼠标坐标。
为什么纯 CSS 做不了真正的鼠标跟随光斑
CSS 的 :hover 本身不提供坐标信息,element.getBoundingClientRect() 和 event.clientX 是 JS 范畴。所有号称“纯 CSS 实现鼠标跟随”的方案,其实都是用 transform: translate() 硬编码固定偏移(比如 translate(20px, -10px)),或依赖焦点/伪类状态切换,而非实时响应鼠标位置。
典型误判场景:
立即学习“前端免费学习笔记(深入)”;
- 把
transition-delay当成“跟随延迟”,实际只是入场时间差 - 用
@keyframes模拟路径动画,但路径是预设的,和鼠标轨迹无关 - 在
:hover中写left: var(--mouse-x)—— 这个变量根本没被 JS 设置,CSS 会忽略
如果真需要跟随效果,必须用 JS 把 clientX/clientY 转为相对容器的百分比,再写入 style.setProperty('--x', x + '%'),CSS 再用 transform: translate(var(--x), var(--y))。否则就是静态动画。
移动端适配和性能陷阱
移动端没有 :hover,iOS Safari 默认不触发 :hover 伪类(除非元素有 touchstart 监听器或 cursor: pointer)。更麻烦的是,光斑动画若未启用 GPU 加速,滚动时极易掉帧。
实操建议:
- 加
cursor: pointer提升 iOS hover 兼容性 - 伪元素务必加
will-change: transform或transform: translateZ(0)强制 GPU 渲染 - 避免在
::before上设box-shadow或多层background,径向渐变已够用 - 慎用
transition: all,只过渡transform和opacity,其他属性会触发重排
光斑效果最易被忽略的点:它不是装饰,而是交互反馈。如果用户没意识到这是可点击区域,或者动画太慢/太突兀,反而削弱可用性。控制好 transition-duration 在 0.3–0.6s 之间,比“炫酷”更重要。


















