必须同时满足父容器有明确宽度、子项设flex-shrink:0(或flex:0 0 auto)、移动端加-webkit-overflow-scrolling:touch,否则滚动失效、动画卡顿、切换双触发;transform:translateX()替代left/margin实现高性能滑动,且需同级面板配合transition:transform。

直接用 transform: translateX() + flex 布局就能做,但关键不是“怎么排”,而是“怎么动不卡、怎么滚不崩”。多数人卡在子项被压缩、滚动条失效、动画跳变这三处。
为什么 overflow-x: auto 在 flex 容器里滑不动
不是 CSS 写错了,是 flex 子项默认会收缩(flex-shrink: 1),把内容压扁了,容器没真正溢出,自然不出现滚动条。
- 必须给每个面板或 tab 项加
flex-shrink: 0(或写成flex: 0 0 auto) - 父容器得有明确宽度限制,比如
width: 100%或max-width: 400px,不能是width: fit-content - 移动端务必加
-webkit-overflow-scrolling: touch,否则惯性滚动直接消失 - 别只写
flex-wrap: nowrap——它只防换行,不等于开启滚动
滑动动画必须用 transform,别碰 left 或 margin
left 和 margin-left 触发 layout(重排),尤其在频繁切换时,iOS 上掉帧明显;transform: translateX() 走合成层,硬件加速,手感顺。
- 所有面板必须同级、并列放在一个
.panels容器内 - 初始状态:当前面板
transform: translateX(0),左邻面板translateX(-100%),右邻translateX(100%) - 过渡只写
transition: transform 0.3s ease,别加left或margin进去 - 切面板后若高度不一致,得手动调用
el.getBoundingClientRect().height更新容器高度,否则留白或遮挡
touchend 代替 click 是硬性要求
iOS 和部分安卓机型上,click 是 touchend 的 300ms 延迟派生事件。同时监听两者,一次手指点击会触发两次切换。
立即学习“前端免费学习笔记(深入)”;
- 只绑
touchend,且回调里必须写event.preventDefault() - 不需要判断设备类型,现代移动端统一走这套逻辑就行
- 别对
display或visibility做 transition——这两个属性不可动画,写了也无效
最常被忽略的是两件事:父容器宽度没设死,和子项没关掉 flex-shrink。这两点一漏,其他都白调。


















