侧边弹窗必须用 position: fixed 而非 absolute,否则滚动时错位、遮罩失效;正确写法为 left/right + top + height: 100vh + z-index;宽度设 320px,用 class 切换控制动画,避免内联样式;遮罩层需独立同级且防冒泡;iOS 键盘弹出时需动态调整定位与高度。

侧边弹窗必须用 position: fixed,别碰 absolute
滚动时弹窗跟着跑、关不掉、遮罩层点无效——八成是用了 position: absolute。它依赖父容器定位,而侧边弹窗要锚定视口,必须用 fixed。
正确写法:left: 0 或 right: 0 配合 top: 0 和 height: 100vh,再加 z-index: 1000 确保压在其他内容上。宽度建议用 width: 320px(兼顾移动端),别用百分比,否则小屏撑满、大屏太窄。
容易踩的坑:
-
transform: translateX(-100%)关闭时只移位不隐藏,会导致点击穿透——得配合visibility: hidden或display: none控制可交互性 - 没设
overflow-y: auto,内容超长时弹窗内部溢出,用户无法滚动查看 - 移动端未加
touch-action: none,手指滑动时可能触发页面缩放或误触背景
openNav() 和 closeNav() 函数里别直接改 style.width
直接操作 style.width = "320px" 会覆盖 CSS 中的 transition,导致动画卡顿或失效。应该用 class 切换来触发 CSS 过渡。
立即学习“前端免费学习笔记(深入)”;
推荐做法:HTML 中给侧边弹窗 div 加初始 class sidebar-closed,CSS 定义:
`.sidebar-closed { width: 0; overflow: hidden; }
.sidebar-open { width: 320px; transition: width 0.4s ease; }`
JS 中只需切换 class:
`function openNav() {
document.getElementById("mySidenav").classList.remove("sidebar-closed");
document.getElementById("mySidenav").classList.add("sidebar-open");
}
function closeNav() {
document.getElementById("mySidenav").classList.remove("sidebar-open");
document.getElementById("mySidenav").classList.add("sidebar-closed");
}`
这样既保留动画控制权,又避免内联样式污染。
点击遮罩层关闭弹窗?先确认是否真需要遮罩层
侧边弹窗常见误区:硬套模态框逻辑,给整个页面加半透明遮罩。其实大多数侧边导航/操作面板并不需要遮罩——它本身已通过视觉权重和位置暗示“当前焦点在此”,加遮罩反而干扰阅读、增加点击误关风险。
如果确实要遮罩(比如用于表单提交确认),注意两点:
- 遮罩层必须是独立
<div>,和侧边弹窗同级,不能包裹它;否则点击弹窗内容会冒泡到遮罩层触发关闭 - 监听遮罩层 click 时,务必检查
e.target === overlayEl,否则点击弹窗内任意元素都会关掉 - 遮罩层要设
tabindex="-1",否则键盘用户 Tab 到遮罩就卡住,无法进入弹窗内容
移动端键盘弹出后弹窗被顶飞?scrollIntoView() 不够用
iOS Safari 下,输入框获得焦点后软键盘弹出,fixed 元素常被错误推离视口顶部,尤其当弹窗高度超过屏幕一半时。仅靠 scrollIntoView() 无法修复。
实操方案:
- 监听
focusin事件,在 input 获取焦点前,临时给弹窗加position: absolute+top: 0,等键盘收起后再切回fixed - 给弹窗容器加
scroll-behavior: smooth,配合scrollTop手动微调位置 - 更稳妥的做法:检测
window.visualViewport?.height变化,若明显缩小(说明键盘弹出),则动态调整弹窗max-height并强制overflow-y: auto
这个细节在桌面端完全不会暴露,但上线后 iOS 用户第一反馈往往就是“点开就看不见弹窗了”——别等 QA 提 bug 再补。



















