手电筒光斑效果需用 radial-gradient 配合 background-clip: text + color: transparent 实现文字镂空,光斑坐标须动态计算相对位置并节流更新,避免 mask-image 等兼容性差方案,加 will-change: transform 提升动画流畅度。

怎么用 radial-gradient 做手电筒光斑
核心是把文字设为透明或镂空,让底层的渐变光斑“透”出来。不能靠阴影或滤镜硬叠,否则边缘发虚、动起来卡顿。
-
background-clip: text+color: transparent是最稳的文字镂空方案,兼容 Chrome/Firefox/Safari(≥15.4) - 光斑必须用
radial-gradient(circle at Xpx Ypx, white, transparent 70%),at后面的坐标要动态更新,别写死成50% 50% - 别用
box-shadow模拟光晕——它无法随鼠标平滑位移,且在 transform 动画中会触发重绘,掉帧明显
鼠标移动时如何实时更新光斑位置
监听 mousemove 获取坐标后,得转换成相对于文字容器的局部坐标,否则光斑会跑偏。
- 用
element.getBoundingClientRect()拿容器位置,再减去event.clientX/clientY,算出相对偏移 - 直接设
style.backgroundPosition最轻量;别用 CSS Custom Property 配合@keyframes,那玩意儿没法实时响应鼠标 - 加
throttle(比如 60ms 一次),不然高频触发会让requestAnimationFrame都救不了——尤其在低配笔记本上,光斑会拖影
为什么 mask-image 方案在 Safari 上容易失效
Safari 对 mask-image + radial-gradient 的组合支持不稳定,特别是配合 transform 或父容器有 overflow: hidden 时,光斑直接消失。
- 错误现象:
mask-image: radial-gradient(...)在 Safari 中完全不生效,但 Chrome 正常 - 根本原因:Safari 要求 mask 的尺寸必须显式声明,得补上
-webkit-mask-size: 200% 200%和-webkit-mask-position: center - 更省事的解法:放弃
mask,回到background-clip: text+ 渐变背景,兼容性好,代码少一半
动画卡顿或光斑闪烁的三个隐藏原因
不是性能差,而是 CSS 层叠和重绘逻辑被误触了。
立即学习“前端免费学习笔记(深入)”;
- 文字父容器没设
will-change: transform,导致每次 backgroundPosition 更新都触发 layout —— 加上它,光斑滑动立刻顺滑 - 用了
filter: blur()给光斑加柔边?小心:blur 会让整个图层进 GPU,内存暴涨,移动端直接卡死;改用多层渐变叠加模拟柔边更安全 - 如果文字是
position: absolute,且父容器transform: translateZ(0),某些旧版 Chrome 会丢弃 background-clip 效果——去掉父容器的 transform,或换用contain: layout paint
background-clip: text 的渲染节奏、还有那一行被忽略的 will-change,才是动效是否“像手电筒”的分水岭。










