translatex()比left更可靠,因其触发硬件加速、不改变文档流、避免滚动重排;left易与overflow:hidden冲突导致卡顿。

侧边菜单用 transform: translateX() 抽屉效果为什么比 left 更可靠
因为 translateX() 触发硬件加速,动画更顺;不改变文档流,不会意外影响其他元素布局;且在移动端滚动时不易被浏览器强制重排。而用 left + position: absolute 容易和父容器 overflow: hidden 冲突,抽屉滑出一半就卡住。
实操建议:
- 始终给侧边栏容器加
will-change: transform(尤其在 Safari 上) - 避免同时设置
transform和top/left/width等布局属性——浏览器可能忽略后者 - 抽屉宽度建议用
rem或%,别用固定px,否则小屏下溢出不可控
如何用纯 CSS 控制抽屉开合状态,不依赖 JS 切换 class
靠 :checked 配合隐藏的 <input type="checkbox"> 最轻量,兼容性好(IE9+),且天然支持键盘空格切换,无障碍友好。
常见错误现象:点击遮罩层关闭不了菜单——其实是遮罩 <div> 没包住 <code><input>,或没用 label[for] 关联。
实操建议:
-
<input id="menu-toggle" type="checkbox" aria-hidden="true">必须放在 DOM 前面,且id和后续label[for]严格一致 - 遮罩层写成
<label for="menu-toggle" class="overlay"></label>,点击即触发 checkbox 取反 - 抽屉本身用
#menu-toggle:checked ~ .sidebar选择器控制位移,别用兄弟选择器+,否则结构稍变就失效
transform: translateX(-100%) 为什么有时不完全隐藏,右边还露一条缝
本质是元素默认有 box-sizing: content-box,而父容器可能设置了 padding 或 border,导致计算偏移时基准错位。更隐蔽的是,某些字体渲染会让子元素实际宽度略大于声明值(尤其含 emoji 或 CJK 字符时)。
实操建议:
- 侧边栏容器统一设
box-sizing: border-box - 位移目标值改用
translateX(-100vw)(注意是vw不是%),确保彻底移出视口 - 如果必须用
%,给侧边栏加max-width: 100vw防止内容撑宽 - 调试时临时加
outline: 1px solid red看真实边界
移动端手势滑动关闭抽屉,CSS 能做吗?还是必须 JS
CSS 本身不支持手势追踪,touchstart/move/end 必须用 JS。但动画部分可以继续交给 CSS——JS 只负责读取滑动距离、动态设置 transform: translateX() 的实时值,并在松手后判断是否超过阈值来决定是补全关闭还是回弹。
性能关键点:这个过程必须用 requestAnimationFrame 更新样式,且只改 transform 和 opacity,别碰 height 或 margin。
实操建议:
- 监听
touchmove时,立刻event.preventDefault()阻止页面滚动干扰 - 松手后用
Math.abs(velocity) > 0.3判断惯性方向,比单纯看位移距离更自然 - 回弹动画用
transition: transform 0.25s cubic-bezier(0.22, 0.61, 0.36, 1),比ease-out更跟手











