纯css抽屉动画最稳方案是用transform: translatex()配合transition,避免display/visibility导致动画失效;遮罩需与侧边栏同级且独立定位;移动端用position: fixed锁body防跳动;须支持esc关闭、焦点管理及tab循环。

点击按钮触发侧边栏滑出,用 CSS transition + transform 最稳
纯 CSS 实现抽屉动画比 JS 操作 left 或 margin 更流畅,也避免重排。关键不是“移入移出”,而是用 transform: translateX() 配合 transition 控制位移过程。
常见错误是直接改 display: none 或 visibility: hidden —— 这会让 transition 失效,因为元素瞬间消失,动画根本没机会执行。
实操建议:
- 侧边栏默认设
transform: translateX(-100%)(完全左移出视口),并加transition: transform 0.3s ease - 触发按钮点击时,给侧边栏加一个类(如
is-open),该类只覆盖transform: translateX(0) - 务必给侧边栏设置固定宽度(如
width: 280px)和position: fixed,否则在 flex 或 document 流中容易错位 - 别忘了加
top: 0; height: 100vh;,否则滚动时侧边栏可能只覆盖可视区一部分
遮罩层(overlay)必须独立定位,且 z-index 要高于侧边栏
点击遮罩关闭抽屉是用户预期行为,但很多人把遮罩写成侧边栏的子元素,结果导致点击无效或层级错乱。
遮罩本质是全屏半透明层,它和侧边栏应是同级兄弟元素,都挂载在 下,否则会被父容器的 overflow: hidden 截断,或受 flex 布局约束无法铺满。
实操建议:
- 遮罩用
<div id="sidebar-overlay"></div>,样式设position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 999; - 侧边栏的
z-index设为1000,确保在遮罩之上;遮罩本身不响应鼠标事件,所以加pointer-events: none;,再给它内部一个空子元素或直接用 JS 绑定点击事件 - 打开时同时添加
is-open到侧边栏和遮罩,并给遮罩加pointer-events: auto;,关闭时再移除
移动端需禁用 body 滚动,但不能用 overflow: hidden 粗暴处理
侧边栏展开时若允许页面滚动,会暴露背景内容、破坏沉浸感。但直接给 加 overflow: hidden 会导致页面“跳动”——因为滚动条消失后,body 宽度突然变宽,右侧内容会右移。
这个问题在 Chrome 和 Safari 表现不一致,Safari 尤其明显。
实操建议:
- 不用
overflow: hidden,改用position: fixed; width: 100%;锁定 body:打开抽屉时给加类no-scroll,其样式为position: fixed; top: -<span id="scroll-top">0</span>px; width: 100%; - JS 中先记录
document.documentElement.scrollTop,赋值给top的负值,这样滚动位置不会丢失 - 关闭抽屉时恢复
position: static并scrollTop回原位置,否则用户返回后页面卡在顶部 - 这个方案兼容 iOS Safari,且无视觉跳变
键盘可访问性:ESC 关闭 + 焦点管理不能漏
仅靠鼠标点击不够。用户按 ESC 应关闭抽屉,且打开后焦点要自动落入侧边栏第一个可聚焦元素(比如首项 <a></a>),否则屏幕阅读器和键盘用户会迷失。
常见疏忽是只监听 ESC,却没处理焦点环(focus ring)被 outline: none 吃掉,或者没限制 Tab 键只能在抽屉内循环。
实操建议:
- 监听
keydown事件,判断e.key === 'Escape',触发关闭逻辑 - 打开抽屉后,调用
sidebarElement.querySelector('a, button, [tabindex]')?.focus() - 实现 Tab 键循环:监听
keydown,当焦点在最后一个可聚焦元素且按 Tab 时,阻止默认行为并 focus 第一个;反之亦然 - 不要全局删
outline,可用:focus-visible替代,或加自定义焦点样式保可访问性
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











