核心是用mousemove监听鼠标位置,计算相对容器的归一化坐标(如-50%~+50%),通过setProperty更新--x/--y CSS变量,CSS中用calc(50% + var(--x))配合background-position实现平滑偏移,并需防抖、设background-size>100%、加will-change优化性能。
mousemove 事件实时更新 --x 和 --y 自定义属性核心是把鼠标坐标转成 CSS 可用的变量,再在 background-position 或 transform 中引用。直接监听 mousemove,计算相对容器中心的偏移比例(比如 -50% 到 +50%),存为 :root 或元素级自定义属性。注意别用 clientX/clientY 原始像素值——它会超出背景图范围导致错位。
实操建议:
window),避免滚动时坐标错乱event.offsetX / container.offsetWidth 算相对横坐标,再乘以 100 得百分比值container.style.setProperty('--x', xPercent + '%'),CSS 里写 background-position: calc(50% + var(--x)) calc(50% + var(--y))
throttle(如 30ms 间隔)防抖,否则高频触发拖慢渲染background-position 实现视差式背景位移比起 transform,background-position 更适合纯背景图偏移,且不会触发重排。但要注意:背景图必须设为 no-repeat 且尺寸大于容器(如 background-size: 120% 120%),否则偏移无效。
常见错误现象:
立即学习“前端免费学习笔记(深入)”;
background-size 是否小于等于 100%
--x 为正时背景向左移,所以公式要用 calc(50% - var(--x)) 调整方向background-size 提高到 130%,并确保 --x/--y 的最大值不超过 ±15%will-change: background-position 避免闪烁和掉帧动态改 background-position 在某些浏览器(尤其是 Safari 和旧版 Chrome)容易触发重绘闪烁或卡顿。不加优化时,每帧都可能走完整布局→绘制流程。
性能关键点:
will-change: background-position,别滥用在父容器上transform: translateZ(0) 强制 GPU 加速(部分安卓 WebView 必需)transform 替代 background-position(比如移动伪元素),记得设 backface-visibility: hidden 防 iOS 渲染异常mousemove,改用 touchmove 并处理多点触控手机上没鼠标,mousemove 不触发。直接换 touchmove 即可,但要注意:touches[0] 才是主触点,别用 changedTouches(它只包含本次变化的点)。
使用场景差异:
event.touches[0].clientX,逻辑同桌面端touchstart 里记下是否有多于一个触点,有则跳过更新touch-action: none 到容器上消除延迟复杂点在于 touch 坐标受页面缩放影响,而 offsetX 在移动端不可靠,得统一用 clientX - container.getBoundingClientRect().left 算相对位置。