sidebar__trigger--is-collapsed是唯一合法的交互状态类名,必须绑定到触发器元素上;sidebar--condensed是推荐的布局响应类名,用于控制容器尺寸收缩,二者语义与职责分离且需js同步控制。

sidebar__trigger--is-collapsed 是唯一合法的交互状态类名
不能写成 sidebar--collapsed 或 sidebar--is-collapsed,因为 BEM 的修饰符(Modifier)必须绑定到**实际承载该交互状态的 DOM 元素**上。用户点击的是汉堡图标、按钮或标题这类触发器(sidebar__trigger),它的视觉变化(旋转、变色、位移)才是“已折叠”这个操作反馈的直接体现。
常见错误现象:
• JS 调用 element.classList.toggle('sidebar--collapsed'),DevTools 里类名存在,但样式不生效
• 动画卡在半途,或收起后文字仍溢出、点击区域还在
• 响应式断点切换时,侧边栏宽度没同步变化
实操建议:
• 状态类只加在触发器上:sidebar__trigger--is-collapsed
• 若需控制侧边栏整体宽度收缩,另设布局类 sidebar--condensed,由 JS 同步添加到 sidebar 元素上
• 两个类绝不混写在同一元素:交互状态和布局响应必须解耦,否则调试时无法区分是点击逻辑错还是尺寸计算错
sidebar--condensed 是唯一推荐的布局响应类名
sidebar--condensed 表达的是容器级的尺寸收缩,不是状态,而是对用户操作的布局响应。它和 sidebar__trigger--is-collapsed 是一对 JS 同步开关的兄弟类,但语义与职责完全不同。
为什么不用 sidebar--collapsed?
• collapsed 暗示“完全坍缩”,但真实场景中 sidebar 容器常保持 position: fixed 和占位,只是内容区不可见或缩窄;
• condensed 更准确:表示“压缩后的布局形态”,不承诺是否隐藏、是否可交互、是否保留 padding;
• 语义清晰利于协作:后端模板或组件库能明确知道这个类只影响 flex-basis / width / overflow,不涉及 JS 状态管理。
实操建议:
• sidebar--condensed 必须配 overflow: hidden 和 min-width: 0,防止内部长文本撑宽
• 宽度过渡必须写在基础类上:.sidebar { transition: flex-basis 0.25s ease; },不能只写在 .sidebar--condensed 里
• 配合 transform: scaleX(0.98) 微调视觉压感(非必需,但比纯宽度动画更稳)
max-height: 0 → 400px 动画失效?先确认是否用了 auto
max-height: 0 → auto 不是合法过渡,浏览器无法插值,结果就是跳变或无动画。这是侧边栏子菜单(sidebar__list)折叠动画最常见的失效原因。
实操建议:
• 展开目标值必须是固定像素上限,例如 max-height: 400px(需预估最大子项高度 + padding)
• 收起始终用 max-height: 0,并配 overflow: hidden
• 更优方案:改用 transform: scaleY(0) → scaleY(1),配合 transform-origin: top,无需预估高度,GPU 加速,且不受 flex-basis 干扰
• 若用 transform,记得给 sidebar__list 加 will-change: transform,尤其在移动端防闪屏
transition 属性必须声明在基础类,而非修饰符类
如果只在 .sidebar--condensed { transition: flex-basis 0.25s ease; } 里写 transition,那么从收缩态切回展开态时动画会失效——因为基础类 .sidebar 没定义 transition,浏览器默认用 transition: all 0s 回退。
实操建议:
• 所有可动画属性(flex-basis、max-width、transform)的 transition 必须写在非状态的基础选择器上,例如:.sidebar { transition: flex-basis 0.25s ease; }
• 避免写 transition: width:width 受 min-width、content、flex-shrink 影响大,容易跳变;优先用 flex-basis 或 max-width
• 如果侧边栏是 flex 项,确保父容器有 display: flex 且未设 flex-wrap: wrap,否则 flex-basis 动画直接失效
最易被忽略的一点:BEM 类名不是“命名习惯”,而是 CSS 作用域契约。写错一个连字符位置(比如 sidebar__trigger-is-collapsed 少了两个横线),就匹配不到选择器;把状态类加错元素,JS 切换就等于白切。调试时第一反应不该是“动画代码有没有问题”,而是打开 DevTools 看 class 列表里有没有那个**完整、拼写正确、加在正确元素上**的修饰符类名。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











