侧滑动画必须用 transform + transition,禁用 display;遮罩层用 rgba() 而非 opacity;需锁 body 滚动并及时释放;菜单容器须设 position: relative 和 overflow: hidden 以明确定位上下文。

侧滑动画必须用 transform + transition,别碰 display
直接写 display: none / display: block 会中断 CSS 动画,且无法触发硬件加速。浏览器对 transform 的优化远好于布局属性变更,尤其在 iOS Safari 上,display 切换还会导致页面重排、白边、甚至意外缩放。
正确做法是用 transform: translateX() 把菜单完全移出视口:
- 隐藏状态:设为
transform: translateX(-100vw)(比-100%更可靠,不受父容器影响) - 显示状态:设为
transform: translateX(0) - 过渡必须加在菜单容器上:
transition: transform 0.4s ease - 避免写成
transition: all 0.4s——它会拖慢其他无关属性的计算
遮罩层要用 rgba(),不是 opacity
遮罩层如果用 opacity: 0.7,整个子树都会变透明,包括你放在里面的手动关闭按钮或菜单项,文字发虚、点击失效,尤其在旧版 Safari 上更明显。
必须用 background-color: rgba(0, 0, 0, 0.7),并配合 z-index 分层控制:
- 默认状态:
.overlay { z-index: -1; } - 激活时:
.overlay.active { z-index: 980; } - 菜单主体 z-index 设为 990,主内容区设为 970,确保层级清晰
- 遮罩层必须加
touch-action: none,否则 iOS 可能跳过 click 直接触发 tap,造成穿透
移动端必须锁 body 滚动,但得及时释放
菜单展开时若不锁 body,用户一滚动,背景页就跟着动,体验断裂;但关掉菜单后若忘记恢复,整个页面就永远不能滚了——这是线上最常被忽略的硬伤。
JS 中要严格配对操作:
- 打开菜单时:
document.body.style.overflow = 'hidden' - 关闭菜单时:
document.body.style.overflow = ''(不能只设auto,清空最稳妥) - 如果菜单内容本身可滚动,其容器必须加
overscroll-behavior: contain,否则滑到底会拖拽背景页 - 不要在
body上直接设overflow: hiddenCSS——它会全局生效,影响其他弹窗
定位上下文不明确,菜单就会“飘”出视口
很多侧滑菜单关不回去、出现水平滚动条,根本原因不是 JS 写错了,而是 position: absolute 的元素找不到合适的 containing block。当菜单用 right: -350px 移出时,若父容器没设 position: relative 或 overflow: hidden,浏览器就把负偏移区域算进视口宽度。
解决方案很简单:
- 给菜单包裹一层
<div id="menu-container"> <li>该容器必须设 <code>position: relative和overflow: hidden - 菜单本身设
position: absolute,并以该容器为定位参考 - 避免把菜单直接塞进
或未约束高度的<nav></nav>里
菜单动画的复杂点不在 JS,而在 CSS 层级与定位上下文的耦合。漏掉任意一个约束,iOS 上就可能白屏、卡死、或滑出去收不回来。











