最稳方案是用原生控制图片对比滑块:两张图绝对定位叠放,通过valueasnumber实时计算遮罩宽度并应用clip-path: inset(0 0 0 x%)或overflow:hidden+mask,需处理safari兼容性、尺寸对齐及可访问性。

原生 <input type="range"> 是最稳、最易控的起点,不用 JS 手写拖拽逻辑,也避免 clip-path 在旧版 Safari 中的兼容性翻车。
用 <input type="range"> 控制两张图裁剪边界
核心不是“动图”,而是把滑块值(0–100)实时转成遮罩宽度百分比,并作用于上层图的 clip-path 或容器 overflow。常见错误是直接用 value 改 left,结果在不同分辨率下错位严重。
- 必须用
event.target.valueAsNumber获取浮点值,它比parseInt(value)更准,尤其在键盘微调(←→)时 - 两张图需绝对定位、尺寸完全一致,且父容器设
position: relative和overflow: hidden - 上层图加
clip-path: inset(0 0 0 X%),X = 100 − valueAsNumber;或更稳妥地用遮罩<div class="mask"> 控制宽度 <li>移动端必须加 <code>touch-action: none到滑块容器,否则 iOS 会抢走 touchmove 事件导致卡顿 - 降级方案:改用
overflow: hidden+ 绝对定位的遮罩层<div id="mask">,通过 JS 设置其 <code>width百分比 - 别用
clip-path: polygon()模拟——计算复杂、性能差,且 Safari 对 polygon 动画支持更弱 - 若坚持用
inset(),务必加will-change: clip-path,但仅对 Safari 16+ 有效 - 测试时用真机 Safari,模拟器常误报“正常”
- 两张图都加
width: 100%; height: 100%; object-fit: cover;,禁止拉伸变形 - 父容器必须设
font-size: 0或display: flex,否则 img 默认是 inline 元素,底部会多出几像素空白 - 如果用
transform: translateZ(0)强制 GPU 加速,反而可能让某些 Android WebView 渲染错位,慎用 - 不要依赖图片原始尺寸做布局,所有尺寸以容器为基准,用 JS 监听
resize后重算一次滑块位置
clip-path: inset() 在 Safari 上失效怎么办
Safari 15.4 之前对 inset() 动态更新支持极差,拖动时会闪退或卡死。这不是写法错,是渲染引擎限制。
为什么图片总对不齐、左右留白不一致
根本原因不是 margin 或 padding,而是两张图没强制等宽高,或容器未设 box-sizing: border-box。
最易被忽略的是键盘焦点管理:<input type="range"> 默认可聚焦,但若没加 tabindex="0" 和 aria-valuenow,屏幕阅读器用户根本无法操作——这不是“增强”,是基础可用性门槛。











