transition 必须写在基础选择器上,而非仅在 hover 或类切换时声明;优先使用 transform + opacity 实现过渡,避免 width 触发重排;需防连点、处理 transitionend 事件过滤、强制初始帧、适配响应式与可访问性。

transition 必须写在基础容器上,不能只靠 hover 或 class 切换时才声明
双栏布局(比如 .sidebar + .main-content)做宽度缩放或显隐过渡时,常见错误是把 transition: width 0.3s 写在 .sidebar.collapsed 里。结果只有收起有动画,展开瞬间“啪”一下弹出来——因为移除 collapsed 类时,transition 规则跟着消失,浏览器没机会记录起始帧。
正确做法是把 transition 声明在基础选择器中:
.sidebar {
width: 240px;
transition: width 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
.sidebar.collapsed {
width: 60px;
}
- 必须显式定义初始
width(不能依赖auto或未设值) - 推荐用
cubic-bezier替代ease,更贴合用户操作节奏 - 如果侧边栏用了
flex布局,确保父容器(如.layout)没意外设置overflow: hidden,否则缩放过程可能被裁剪
别用 width 或 margin 做主过渡,优先走 transform + opacity 组合
直接过渡 width 会触发重排(reflow),尤其在内容多、字体加载慢的页面上,容易卡顿甚至跳帧。现代双栏交互更稳的方案是固定宽度 + 视觉位移:
生成可在 deepbi 沙箱 iframe 内运行或作为独立文件运行的交互式 HTML 页面,使用 `window.deepbi` JS SDK 实现数据查询、空间管理、文件浏览及用户操作。当用户提出以下需求时启用该能力: - 创建 KPI 仪表盘、数据表格、文件浏览器、成员列表、管理页面; - 明确要求“转成 dhtml”、“转译成 HTML”、“把 XX 页面转成……”、“控制台页面”、“管理后台”、“DeepBI 页面迁移”; - 提及位于 `apps/console/src/featur
.sidebar {
width: 240px;
transform: translateX(0);
transition: transform 0.3s, opacity 0.25s;
}
.sidebar.collapsed {
transform: translateX(-180px);
opacity: 0.85;
}
-
transform和opacity走 GPU 合成层,不干扰布局流 - 配合
opacity: 0.85(不是0)可保留可点击区域,避免鼠标悬停失焦 - 若需完全隐藏交互,加
pointer-events: none,但必须和opacity分开控制——opacity: 0本身不阻止事件 - 注意:
transform会创建新的层叠上下文,若.sidebar内有下拉菜单需覆盖.main-content,得给它设z-index
JS 控制状态切换时,要防连点错乱和 transitionend 监听失效
点击按钮切换双栏收展状态,如果用户快速连点,容易出现状态和动画不同步:比如点了两次“收起”,.collapsed 类已存在,但 transitionend 仍被触发,导致后续逻辑错乱。
- 加状态锁:
if (sidebar.classList.contains('collapsing')) return;,并在动画开始前加collapsing类,结束时移除 -
transitionend必须过滤属性名:if (e.propertyName !== 'transform') return;,避免opacity结束也触发回调 - 用
getComputedStyle读一次transform值(如void sidebar.offsetHeight),可强制浏览器拍下初始帧,解决首次动画不播问题 - 移动端 Safari 对
transform动画降级敏感,建议在父容器加will-change: transform
响应式断点切换时,transition 容易被媒体查询覆盖
在 @media (max-width: 768px) 里把双栏改成单栏堆叠,若只在小屏下设 transition,大屏切回时动画就没了;反之亦然。根本原因是媒体查询规则优先级高于普通样式,且切换过程不保证过渡连续。
- 所有尺寸下的
transition都应写在基础选择器中,不要拆到媒体查询内部 - 用 CSS 变量统一控制关键参数:
--sidebar-width: 240px;,再通过媒体查询改变量值,保持transition始终生效 - 避免在媒体查询中用
display: none→block切换侧边栏——这完全绕过 transition,改用visibility: hidden+opacity: 0+transform - 如果用 JS 检测窗口 resize 并手动加类,记得节流,否则频繁触发会导致 transition 多次重置
实际最难的部分不是让宽度动起来,而是判断「什么时候不该动」:比如用户正在滚动、键盘导航聚焦在侧边栏内、或者屏幕阅读器开启时,过渡反而干扰可访问性。这些边界情况,CSS 无法自动感知,得靠 JS 配合 prefers-reduced-motion 媒体查询或焦点管理来兜底。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










