用transform: translateX()+transition是最稳最轻量的移动端侧边栏滑动方案,因不触发重排、GPU加速、兼容性好且不干扰文档流;必须设fixed定位、明确宽度、基础状态写全transition,禁用display:none。

用 transform: translateX() + transition 是目前最稳、最轻量的方案,别碰 width、left 或 display: none —— 它们要么卡顿,要么动画失效,要么破坏焦点和状态。
为什么必须用 translateX() 而不是 left 或 margin-left
改 left 会强制浏览器每帧重排(reflow),尤其在安卓低端机或 iOS WebView 里,滑动一卡一卡;margin-left 在某些布局下还会意外撑开父容器或触发滚动条。translateX() 属于合成层操作,走 GPU 加速,不干扰文档流,主内容区不会“晃一下”。
- 初始状态写成
transform: translateX(-100%),不是translate(-100%)(缺轴向)或translateX(-100)(漏单位) - 侧边栏必须设明确宽度(如
width: 280px),否则-100%按父容器算,可能滑不全 - 别给侧边栏加
position: absolute后再用translateX()——滚动时它会跟着跑;position: fixed才是底线
transition 必须写在哪?怎么写才不翻车
transition 必须声明在侧边栏的基础 CSS 规则里,不能只写在 .sidebar--open 这类状态类中,否则 class 切换时没有过渡效果,直接“瞬移”。
- 正确写法:
transition: transform 0.3s ease;—— 只过渡transform,避免意外带出其他属性动画 - 别写
transition: all 0.3s,后续加了color或opacity就会干扰逻辑 - 别把
transition放在:hover或 JS 内联样式里,CSS 优先级和声明时机会导致失效 - 初始状态不能是
display: none,否则transform和transition全部不生效;可用visibility: hidden配合pointer-events: none临时隐藏
移动端弹出后背景还能滚动?Safari 卡顿闪屏?
这是 Safari 对合成层处理保守导致的,尤其当侧边栏内有图片、阴影或 border-radius 时,首帧容易掉帧或渲染异常。
立即学习“前端免费学习笔记(深入)”;
- 父容器必须加
overflow-x: hidden(不是overflow: hidden),否则横向滚动条可能漏出 - 侧边栏自身加
will-change: transform提前提示渲染引擎,但别滥用——只在动画触发前加,收起后移除 - 遮罩层
.overlay不仅用于点击关闭,更要防止背景穿透点击;它得和侧边栏同级,且z-index略低 - JS 控制显隐时,先用
window.matchMedia('(max-width: 767px)').matches判断是否小屏,只在该条件下执行classList.toggle('sidebar--open'),避免大屏误触
真正难的不是让侧边栏动起来,而是让它动完之后,内部表单不重置、地图不崩、焦点不丢、遮罩层不漏点——这些都依赖“元素始终在 DOM 中”,而不是靠 display: none 反复卸载。平滑只是表象,稳定才是关键。


















