纯CSS侧边滑出动画可用transform+transition实现,核心是translateX(-100%)到translateX(0)配合transition,结合checkbox+label无JS控制,需注意定位、性能优化、可访问性及移动端适配。

用 transform + transition 实现侧边滑出动画
纯 CSS 就能搞定,不需要 JS 控制动画过程。核心是把面板初始设为 transform: translateX(-100%)(完全左移出视口),再通过 class 切换触发 transform: translateX(0),配合 transition 实现平滑滑入。
关键点:
-
position: fixed或absolute是必须的,否则面板会挤占文档流,影响主内容布局 - 动画时间建议设为
0.3s左右,太快不易察觉,太慢显得卡顿 - 别忘了加
will-change: transform提升动画性能(尤其在移动端) - 如果面板宽度不固定,用
max-width配合width: fit-content更稳妥
用 checkbox + label 实现无 JS 开关逻辑
想避免写 JS?可以用隐藏的 input[type="checkbox"] 绑定 label,靠 :checked 伪类控制面板显隐。这是语义清晰、可访问性好、且真正“无 JS”的方案。
常见结构:
立即学习“前端免费学习笔记(深入)”;
<input type="checkbox" id="sidebar-toggle" hidden>
<label for="sidebar-toggle" class="toggle-btn">☰</label>
<aside class="sidebar">...</aside>
.sidebar {
transform: translateX(-100%);
transition: transform 0.3s ease;
}
#sidebar-toggle:checked ~ .sidebar {
transform: translateX(0);
}
注意:
-
~是通用兄弟选择器,确保input在.sidebar前面声明 - 移动端点击区域小?给
.toggle-btn加padding和touch-action: manipulation - 这个方案无法监听“关闭后执行某操作”,如需回调,还是得上 JS
用 aria-expanded 和 aria-controls 保证可访问性
屏幕阅读器用户依赖这些属性理解控件状态。只靠视觉变化(比如按钮变色)是不够的。
必须同步更新的属性:
- 按钮上加
aria-expanded="false"(初始)和aria-controls="sidebar-id" - 面板上加
id="sidebar-id"和role="region"(或role="complementary") - 每次开关时,JS(如果有)要同步切换
aria-expanded值 - 别漏掉
tabindex="-1"到面板上,方便 JS 聚焦,提升键盘导航体验
移动端适配:防止滑动穿透和滚动截断
面板展开时,如果主内容还能滚动,手指一滑就容易误触背景页——这叫“滚动穿透”。解决它不能只靠 overflow: hidden 在 body 上,那会导致页面跳回顶部。
更稳的做法:
- 给
body加position: fixed; width: 100%; top: -${scrollTop}px(JS 记录并还原滚动位置) - 或者用
overscroll-behavior: contain在面板内部容器上,阻止滚动溢出 - iOS Safari 对
position: fixed+transform动画有渲染 bug,加backface-visibility: hidden可缓解 - 如果面板内容长于视口,确保其内部可滚动:
max-height: 100vh; overflow-y: auto
最常被忽略的是:没处理键盘焦点陷阱。用户按 Tab 键时,焦点不该逃出面板,也不该卡在第一个元素。这部分需要 JS 主动管理 focusable 元素范围。



















