用 CSS transform + transition 实现侧边滑动图片窗,关键在于外层容器 overflow: hidden 与图片容器 flex 布局配合 translateX 定位,配合 JS 防重复点击、边界截断和键盘/手势支持。

用 CSS transform + transition 实现侧边滑动图片窗
直接用 transform: translateX() 控制图片容器的水平位移,配合 transition 做缓动,比 JS 动画更轻量、更顺滑。关键不是“怎么动”,而是“怎么触发”和“怎么复位”。
常见错误是把所有图片堆在一行后硬塞进固定宽容器,结果溢出被裁、滚动条乱跳,或者点击后位置错乱。正确做法是让容器宽度等于单张图宽 × 图片数,再用一个外层 div 设为 overflow: hidden 来做可视窗口。
- 给图片容器设
display: flex,每张图用flex: 0 0 100%占满视口宽度 - 外层容器设
width: 100%; overflow: hidden;,避免页面横向滚动 - 用一个变量(比如
currentIndex)记录当前页,每次点击只更新transform: translateX(-${currentIndex * 100}%) - 别用
left或margin-left做位移——重排开销大,动画卡顿明显
用 JavaScript 控制滑动逻辑(不依赖框架)
不需要 jQuery 或轮播库,原生 JS 几十行就能搞定。重点是事件绑定要防重复点击、边界判断要严格、滑动后要禁用按钮直到动画结束。
典型问题:快速连点导致 currentIndex 超出范围,或动画未结束就触发下一次位移,造成错位。解决方案是加锁状态 + 边界截断。
立即学习“前端免费学习笔记(深入)”;
- 用
let isAnimating = false控制开关,transitionend触发后才置为false - 翻页前先检查:
if (isAnimating || currentIndex === 0 && direction === 'prev') return - 移动后立即更新
currentIndex,但位移值必须用Math.max(0, Math.min(maxIndex, newIndex))截断 - 按钮
disabled状态建议同步更新,比纯靠 JS 锁更直观
响应式适配:图片宽度不能写死 px
写成 width: 300px 的图片在手机上会撑破容器。必须用百分比或视口单位,且容器结构要支持缩放。
错误做法是给 img 标签设 width: 100vw——它会随整个视口变,但实际需要的是“占满当前滑动窗宽度”。正确方式是让滑动窗本身响应式,图片继承其宽高比。
- 外层容器用
width: 100%; max-width: 800px; margin: 0 auto;居中并限制最大宽 - 每张图的容器设
flex: 0 0 100%,图片设width: 100%; height: auto; display: block; - 如果需保持宽高比,给图片容器加
aspect-ratio: 16/9(现代浏览器),旧版用 padding-top 技巧 - 慎用
object-fit: cover——它会裁剪,若原图比例差异大,可能切掉关键内容
键盘与手势支持(← → 方向键 + swipe)
仅鼠标点击不够,用户习惯按方向键或左右滑。PC 端监听 keydown 很简单,移动端的 touch 事件容易误判,得过滤小位移和长按。
常见坑是 touchmove 触发太频繁、没清除上次 touchstart 的坐标,导致 swipe 方向识别错乱。核心是只记第一次 touchstart 的 clientX,在 touchend 时比对差值。
- PC:监听
document.addEventListener('keydown', e => { if (e.key === 'ArrowLeft') prev(); else if (e.key === 'ArrowRight') next(); }) - 移动端:touchstart 存
startX = e.touches[0].clientX,touchend 取endX = e.changedTouches[0].clientX - 只在
Math.abs(startX - endX) > 50且endX 时触发 next,反之 prev - 记得在 touchmove 里加
e.preventDefault()防止页面滚动干扰(但仅限容器内)
滑动惯性、回弹效果、自动轮播这些属于增强需求,基础侧边滑动的核心就三点:容器布局合理、位移用 transform、状态控制不越界。其他都是锦上添花,先确保这三块不出错,再考虑加。


















