能实现拖拽感,但必须用 transform: translatex() + transition 配合 js 实时计算位移;纯 css 仅支持二态切换,无法处理松手、阈值、回弹等交互逻辑。

能,但必须用 transform: translateX() + transition,且初始状态、触发时机、事件隔离三者缺一不可;纯 CSS(比如 checkbox hack)可实现基础开关,但拖拽跟随、速度判断、回弹阈值等交互逻辑仍需 JS。
为什么不能只靠 CSS transition 实现“拖拽感”
浏览器的 transition 只响应属性值变化,不感知手指位移过程。用户手指滑动时,需要实时计算并更新 transform: translateX() 值——这一步必须由 JS 在 touchmove 中完成。
- 纯 CSS 的
:checked或:hover只能做“开/关”二态切换,无法响应中途松手、滑动距离不足、惯性回弹等行为 - 所谓“CSS 实现动画”,实际是指动画本身由 CSS 驱动(
transition或@keyframes),但控制权必须交给 JS - 如果强行用
@keyframes模拟拖拽,会因帧率固定、无法绑定 touch 事件而卡顿或失步
transform: translateX() 必须写死初始值,且不能依赖 display: none
transform 动画失效最常见的原因是初始状态没显式声明。浏览器对 none → translateX(0) 不做插值,结果就是“闪一下”或“瞬移”。
使用 JSON Schema 验证 JSON 数据,从示例 JSON 生成 schema,并将其转换为 TypeScript 接口、Python 数据类或 Markdown 文档。
- 侧边栏基础 class 必须包含
transform: translateX(-100%),单位不能省(如translateX(-100)无效) - 禁用
display: none或visibility: hidden控制显隐——它们会让元素脱离渲染树,transform和transition全部失效 - 推荐始终让元素在 DOM 中,仅靠
translateX(-100%)移出视口,保持事件流和布局上下文稳定 -
transition必须写在基础 class 上(如.sidebar),不能只写在.sidebar.open里
body 溢出隐藏必须动态加 class,且要配 overscroll-behavior
抽屉打开时若不锁 body 滚动,iOS 上会出现背景内容被拖拽、松手回弹的“晃动”现象,这不是 JS 问题,是滚动穿透。
- 定义
.no-scroll { overflow: hidden; height: 100vh; },并在 JS 打开抽屉时给document.body添加该 class - 关闭抽屉时**立即移除**,不要等
transition结束——否则用户还能滑两下 - 补上
body.no-scroll { overscroll-behavior: contain; },阻止 iOS 的 bounce 效果 - 遮罩层(overlay)必须用
position: fixed; width: 100vw; height: 100vh;,不用100%(安卓某些 WebView 下算错高度)
移动端 touchmove 位移计算不能只看 clientX 差值
直接用 touchstart.clientX - touchmove.clientX 算偏移,在页面缩放、快速滑动、多指操作下误差大,容易飞走或卡住。
- 正确做法:在
touchstart时记录el.getBoundingClientRect().left作为基准位置 -
touchmove中每次用当前touch.clientX - startClientX + startLeft更新transform - 绑定
touchstart时必须传{ passive: false },否则preventDefault()被静默忽略,滚动拦不住 - 拖拽中动态加
style="will-change: transform;",拖完立刻移除;别和translateZ(0)叠加用
真正“流畅”的关键不在动画曲线多 fancy,而在初始渲染不掉帧、滚动不穿透、拖拽不跳变——这些全是细节堆出来的,改错一个就卡顿。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










