transition 必须作用在实际发生位置/尺寸变化的元素本身,如.sidebar需设初始transform并过渡transform而非all;侧边栏用fixed定位+z-index覆盖内容;关闭动画需同步class控制overlay与sidebar;拖拽需js配合transition收尾。

transition 要作用在哪个元素上才有效
必须作用在「实际发生位置/尺寸变化的元素」本身,而不是它的父容器或触发按钮。常见错误是给 .sidebar 加了 transition: all 0.3s,但没给它设初始 transform 或 left 值,导致第一次点击无动画——因为 CSS 过渡只响应「已有值 → 新值」的变化,不响应从无到有的渲染。
推荐写法:.sidebar 初始设 transform: translateX(-100%),展开时切到 transform: translateX(0),同时加 transition: transform 0.3s ease-out。这样浏览器能明确追踪变换起点和终点。
- 别用
display: none ↔ block触发 transition——display不可过渡 - 避免同时过渡
width和opacity:宽度变化可能引发重排(reflow),影响性能 - 移动端要注意
transform触发硬件加速,比left更顺滑
如何让侧边栏盖在内容上方且不挤占主区域
关键不是靠 float 或 inline-block,而是用定位 + 层级控制。抽屉式侧边栏本质是「覆盖层」,不是布局流中的一部分。
典型结构:<div class="app">
<div class="sidebar"></div>
<main class="content"></main>
</div>。此时:
-
.sidebar设position: fixed(或absolute),top: 0、height: 100vh、z-index: 1000 -
.content不需要margin-left预留空间——它保持自然流,侧边栏靠定位「浮」在上面 - 如果用
transform移入移出,.sidebar的width应固定(如width: 280px),否则 translateX 百分比计算会失准
点击遮罩层关闭时动画卡顿或闪一下
这是由于遮罩层(overlay)和侧边栏的显示/隐藏时机不同步造成的。比如先设 .sidebar { display: none },再改 transform,或者用 visibility: hidden 但没配好 transition 触发时机。
可靠做法是全程只靠 class 控制状态,用两个 class 分别表示「关闭态」和「开启态」,并确保所有过渡属性都在同一元素、同一时机生效:
- 关闭时:先移除
is-open类 → 浏览器立刻开始transform动画 → 动画结束(监听transitionend)后再设置pointer-events: none防止误点 - 遮罩层
.overlay必须和.sidebar共享同一个is-open类,用相同 transition 时间,且 opacity 从 0 → 0.5 同步动画 - 别在
transitionend里直接删 class——容易因多次触发造成状态错乱,建议加防抖或用once选项
移动端触摸后侧边栏无法拖拽滑动
CSS transition 本身不支持手势拖拽,它只是「从 A 到 B 的自动补间」。要实现手指拖动侧边栏实时跟随,必须配合 JavaScript 监听 touchstart/touchmove,动态更新 transform: translateX() 值,并在 touchend 后判断松手位置决定是回弹还是完成展开。
但注意:一旦进入 JS 手动控制位移,就暂时绕过了 CSS transition。所以真实项目中通常分两层逻辑:
- 用户拖拽时:用
requestAnimationFrame实时设transform,禁用 transition - 松手瞬间:根据拖动距离和速度,用
classList.add('is-open')或classList.remove('is-open')触发 CSS 过渡收尾 - 务必在
touchmove中调用event.preventDefault(),否则 iOS 会触发页面滚动
这个交界点最容易出 bug:比如松手后 transition 没生效,是因为 class 切换太晚,或样式优先级被其他规则覆盖。建议把展开/收起的 transform 值统一用 CSS 自定义属性(--sidebar-translate)管理,JS 只改变量,CSS 负责过渡。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











