flex-shrink: 0是防止Tab标签被压缩的关键,需配合display: flex、overflow-x: auto及text-overflow: ellipsis等实现可滚动单行效果;滑动门定位须用requestAnimationFrame确保时机准确,并考虑scrollLeft与缩放比修正。

flex-shrink: 0 是防止标签被压缩的关键
横向滚动的 Tab 标签栏一旦遇到窄屏或文字长度不一,flex-shrink: 1(默认)会让标签自动缩窄,导致文字截断、图标挤压甚至换行。这不是你想要的“可滚动”,而是“被浏览器强行折叠”。
必须显式设为 flex-shrink: 0,配合 display: flex 和 overflow-x: auto 才能确保每个标签保持原始尺寸、强制单行、靠滚动查看。
- 别用
white-space: nowrap代替——它只防换行,不阻止 flex 自动压缩 - 移动端记得加
-webkit-overflow-scrolling: touch,否则惯性滚动失效 - 标签内文字过长时,组合使用
text-overflow: ellipsis+white-space: nowrap+overflow: hidden
内容区滑动必须用 transform: translateX(),不是 left 或 margin
想让面板左右滑入?直接改 left 或 margin-left 会触发 layout(重排),动画卡顿明显;而 transform: translateX() 走合成层,性能好且支持硬件加速。
关键点是:所有面板需同级排列(比如都放在 .panels 容器内),用绝对定位或 position: relative + left: 0 做初始定位,再通过 JS 动态设置当前面板的 transform: translateX(0),其他面板设为 translateX(-100%) 或 translateX(100%)。
-
transition: transform 0.3s ease比linear更符合手指滑动直觉 - 切换后若面板高度不一致,得调用
getBoundingClientRect()更新容器高度,否则留白或遮挡 - 别对
display或visibility做 transition——这两个属性不可动画
touchend 代替 click 是移动端不双触发的硬要求
iOS 和部分安卓机型上,同时监听 click 和 touchend 会导致一次点击触发两次切换——因为 click 是 touchend 的 300ms 延迟派生事件。
正确做法是:只绑 touchend,并在回调里调用 event.preventDefault(),彻底阻断后续 click 流程。不需要额外判断设备类型,现代移动端统一走这套逻辑就行。
- 别写
if ('ontouchstart' in window)再分两套事件——既冗余又容易漏掉 hybrid 场景 - 如果还要兼容鼠标操作(比如桌面调试),可以用
pointerdown统一替代,但要注意 IE11 不支持 - 快速连点时,建议在
touchend回调开头加节流,比如用Date.now()判断间隔是否小于 300ms
滑动门定位要基于 offsetLeft + offsetWidth,且在 requestAnimationFrame 中计算
Tab 标签点击后,高亮指示条(滑动门)要精准滑到对应位置。直接读取 offsetLeft 可能不准——因为标签可能刚被动态插入、字体还没加载完、或父容器有 padding 影响。
安全做法是把定位计算放进 requestAnimationFrame 回调里,确保 DOM 渲染完成后再取值;位移目标 = tab.offsetLeft + tab.offsetWidth / 2 - indicator.offsetWidth / 2(居中对齐)。
- 别在事件回调里立刻执行
indicator.style.transform = ...——此时布局可能未就绪 - 如果 Tab 标签用了
transform或scale,offsetLeft仍按原始尺寸返回,得手动乘缩放比 - 滚动容器有
scrollLeft时,要加上该偏移量,否则指示条会错位
滑动门看着只是个视觉动效,真正卡住人的从来不是那几行 transform,而是时机(requestAnimationFrame)、精度(offsetLeft + scrollLeft)、以及事件绑定方式(touchend + preventDefault)这三处细节。漏掉任意一个,都会在真机上出问题。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











