弹窗和侧边栏必须拆成两个独立 Block,因二者职责、DOM 位置、层叠需求完全不同;modal 负责模态中断,sidebar 负责常驻布局,强行共用前缀(如 modal__sidebar)破坏 BEM 模块边界。

弹窗和侧边栏必须拆成两个完全独立的 Block,不能共享命名前缀或混用元素层级;它们之间不存在父子、嵌套或语义从属关系,强行拉通类名前缀(比如都叫 modal 和 modal__sidebar)会直接破坏 BEM 的模块边界。
为什么 modal 和 sidebar 不能共用同一个 Block 名
常见错误是把侧边栏当作弹窗的子功能,写成 modal__sidebar 或 modal__drawer。这违反了 BEM 最基本前提:Block 必须代表一个可独立复用、有明确职责边界的 UI 单元。
-
modal职责是遮罩 + 内容浮层 + 状态控制(显隐、z-index、动画触发),它依赖 fixed 定位和全局层叠上下文 -
sidebar职责是页面局部布局容器,通常跟随文档流或固定在视口一侧,不强制需要遮罩,也不参与弹窗级 z-index 排序 - 两者 DOM 位置、交互逻辑、CSS 层叠需求完全不同——把它们塞进同一 Block,等于让一个类同时承担「模态中断」和「常驻导航」两种矛盾语义
多个弹窗类型(confirm / toast / drawer)怎么隔离
不是靠加长元素名(如 modal__confirm-overlay),而是为每种类型定义独立 Block,并用统一的 CSS 自定义属性管理 z-index。
- 确认框:
confirm(不是modal--confirm) - 通知提示:
toast - 抽屉面板:
drawer - 所有 Block 在
:root中声明语义化 z-index:--z-confirm: 1100、--z-toast: 900、--z-drawer: 1000 - 每个 Block 根节点绑定:
.confirm { z-index: var(--z-confirm); },子元素(如confirm__overlay)不设 z-index
sidebar 的修饰符该加在哪一级
sidebar--collapsed 必须作用于 sidebar 根节点,而不是 sidebar__trigger 或 sidebar__list —— 它描述的是整个侧边栏的状态,不是某个按钮或列表的行为。
立即学习“前端免费学习笔记(深入)”;
- 收起时,JS 只需切换根节点类名,CSS 通过
.sidebar--collapsed .sidebar__list控制隐藏逻辑 - 禁止写
sidebar__trigger--collapsed:触发器只是状态入口,不是状态载体 - 若存在 admin/user 两类侧边栏,用
sidebar--admin和sidebar--user扩展,而非新建 block 名(如admin-sidebar)
transition 为什么不能写在 --visible 或 --collapsed 类里
过渡效果必须定义在基础类(如 modal__overlay、sidebar__list)中,否则移除状态类时动画会立即跳变。
- 正确:
.modal__overlay { opacity: 0; visibility: hidden; transition: opacity 0.2s ease, visibility 0.2s step-end; } - 错误:
.modal--visible .modal__overlay { opacity: 1; transition: opacity 0.2s; }→ 隐藏时无 transition - 更错:
.sidebar__list { display: none; }→display不可过渡,必须用visibility + transform或max-height
真正难的不是写对类名,而是每次加新组件前,先问一句:它能不能脱离当前页面单独存在?如果答案是否定的,那就还没达到 Block 级别,得重构 DOM 和 CSS 边界。


















