
侧边栏用 transform: translateX() 实现弹出,别用 left 或 margin-left
用 transform 位移是唯一靠谱的方案:动画顺滑、不触发重排、支持硬件加速。用 left 或 margin-left 拉拽侧边栏,页面会卡顿,尤其在低端安卓机上——因为每次变化都强制浏览器重新计算布局。
常见错误现象:transform: translateX(-100%) 后侧边栏看不见了,但点击区域还在;或者弹出后背景内容还能滚动。
- 初始状态设为
transform: translateX(-100%),宽度固定(比如width: 280px),同时加will-change: transform提前提示渲染引擎 - 弹出时切换 class,改成
transform: translateX(0),别用transition: all .3s—— 只写transition: transform .3s ease,避免意外过渡其他属性 - 必须给侧边栏父容器加
overflow: hidden,否则 Safari 下可能漏出滚动条或内容溢出
媒体查询断点要和 JS 控制逻辑对齐,别只靠 CSS
纯 CSS 媒体查询能隐藏侧边栏(display: none),但无法解决“小屏弹出、大屏常驻”的混合逻辑。一旦你在 JS 里用 classList.toggle('open') 控制显隐,而媒体查询又把侧边栏设为 display: block,就会冲突。
使用场景:PC 屏幕下侧边栏默认展开,移动端收起,点击按钮弹出。
立即学习“前端免费学习笔记(深入)”;
- 媒体查询只负责“是否允许弹出”:比如
@media (min-width: 768px) { .sidebar { transform: translateX(0); } },让大屏直接显示,不依赖 JS - JS 只响应点击事件,且先判断
window.matchMedia('(max-width: 767px)').matches,只在小屏下才执行toggle - 别在 CSS 里写
@media (max-width: 767px) { .sidebar { display: none; } },否则 JS 切换 class 无效——display: none优先级高于transform
position: fixed 是侧边栏定位的底线,别用 absolute
用 position: absolute 的后果很直接:滚动页面时侧边栏跟着跑,遮不住主内容,也盖不住底部导航。只有 fixed 能让它真正“浮”在视口上,和 body 解耦。
性能影响:fixed 元素脱离文档流,不会影响主内容重排,但要注意 z-index 层级。
- 必须设
top: 0; bottom: 0;,不能只写top: 0,否则在长页面里拉到底部,侧边栏就截断了 -
z-index至少设为1000,避免被第三方组件(如 toast、modal)压住;如果用了 CSS-in-JS 库,注意它的 z-index 是否全局覆盖 - 别忘了加
height: 100vh,而不是height: 100%,后者依赖父元素高度,在 flex 布局里容易塌陷
触摸设备上拖动关闭?小心 touchmove 和 transform 的兼容性坑
iOS Safari 对 transform + touchmove 的组合有延迟,用户手指一划,侧边栏半天没反应。这不是 bug,是浏览器为了防止误触做的优化,但在这里成了障碍。
参数差异:Chrome 安卓基本没问题,iOS 必须加 -webkit-overflow-scrolling: touch 和 touch-action: pan-x 才能响应横向拖动。
- 给侧边栏容器加
touch-action: pan-x,禁用默认的纵向滚动识别 - 监听
touchstart/touchmove时,立刻调用event.preventDefault(),否则 iOS 会吞掉事件 - 别用
getBoundingClientRect().left算偏移量——它在transform下不准;改用getComputedStyle(el).transform解析矩阵,或直接存当前 translateX 值在 data 属性里










