最稳方案是用<input type="range">控制clip-path: inset(),因其轻量、兼容性好且不受DPR、加载延迟影响;其他方式如left或transform易导致错位、卡顿或白边。

直接用 <input type="range"> + clip-path 是最稳的路径,不用第三方库、兼容现代浏览器、键盘可操作、无障碍友好——但必须控制图片尺寸一致、容器宽高明确、移动端加 touch-action: none,否则拖拽会触发页面滚动或卡顿。
为什么不能只靠 CSS transform 拖动滑块分界线
单纯移动一个 .slider-handle 的 transform: translateX() 只是视觉位移,两张图本身仍是全量渲染,无法实现“左侧显示原图、右侧显示对比图”的裁剪逻辑。用户看到的是两个图叠在一起+一条线,不是真正的像素级对比。
- 真正起作用的是对两张
<img>分别施加clip-path或overflow控制可见区域 -
clip-path: inset(0 calc(100% - var(--pos)) 0 0)用于后图,clip-path: inset(0 0 0 calc(100% - var(--pos)))用于前图 - 如果用
transform直接平移图片,会导致错位、白边、响应式重排时跳变
如何让 <input type="range"> 精准驱动裁剪位置
关键不是读取 value 字符串,而是用 valueAsNumber 获取 0–100 的数值,并映射为 CSS 自定义属性,由 CSS 引擎实时计算裁剪边界,避免 JS 频繁写 style。
- HTML 中设
<input type="range" min="0" max="100" value="50" id="slider"> - JS 监听
input事件(不是change),更新style.setProperty('--pos', slider.valueAsNumber + '%') - CSS 中两张图分别用
clip-path引用该变量,无需 JS 操作 DOM 裁剪逻辑 - 移动端必须加
touch-action: none到滑块容器,否则 iOS Safari 会拦截 touchmove 导致拖拽中断
响应式图片加载与对比滑块怎么共存
滑块组件要求两张图尺寸严格一致,但 srcset 加载的图在不同 DPR 下可能自然缩放,破坏像素对齐。必须提前约束输出尺寸或统一用 object-fit: cover。
立即学习“前端免费学习笔记(深入)”;
- 服务端或构建流程中,确保
before.jpg和after.jpg输出为相同分辨率(如都 1200×800) - 若必须用
srcset,则两张图的srcset列表要完全一致,且sizes值相同,否则浏览器可能选不同尺寸源 - 给
<img>加width和height属性(非 CSS),防止加载前布局偏移;再用max-width: 100%+height: auto保证缩放不拉伸 - 监听
load事件后检查naturalWidth,不一致就 warn 或 fallback,避免静默错位
最容易被忽略的是:滑块初始位置设为 50% 时,两张图的 clip-path 计算必须互为补集,否则会出现 1px 缝隙或重叠。这个边界值在高 DPR 设备上尤其敏感,建议用 calc(var(--pos) * 1px) 替代百分比做微调,而不是依赖浮点渲染精度。



















