弹窗多层结构须用BEM的block-element关系显式表达,modal__overlay必须是Element而非独立Block;modal--visible必须加在根节点;transition须定义在基础类;z-index由block统一控制;modal__overlay必须用position: fixed; inset: 0。

弹窗的多层结构必须用 BEM 的 block-element 关系显式表达,不能靠 DOM 嵌套或 CSS 后代选择器隐含层级。
modal__overlay 必须是 Element,不是独立 Block
遮罩层不是功能完整的 UI 单元,它没有独立内容、不承载业务逻辑、无法脱离 modal 存在。写成 .overlay 或 .modal-overlay 都会破坏语义闭环。
-
.modal__overlay✅ 表明它是.modal的直属子元素,JS 控制显隐时只需操作.modal--visible一个状态类 -
.overlay❌ 全局命名冲突风险高(loading、tooltip、drawer 都可能需要遮罩) -
.modal-overlay❌ 单连字符混淆了 Block 和 Modifier 边界,BEM 解析器无法识别归属关系
modal--visible 必须加在根节点上
状态修饰符作用位置错了,整个动画和交互就会断裂。它不是描述某个子元素的外观,而是声明“这个弹窗组件当前处于可见状态”。
- 正确:
<div class="modal modal--visible">,所有子元素通过 <code>.modal--visible .modal__overlay等选择器响应 - 错误:
<div class="modal__overlay modal__overlay--visible"> → 遮罩显示了,但 <code>.modal__content还卡在transform: translateY(100%) - 更错:
<div class="modal--visible__overlay"> → 语法非法,BEM 不允许修饰符出现在 element 名前 <h3>transition 必须定义在基础类里,不能塞进 --visible</h3> <p>把 <code>transition写在.modal__overlay--visible里,会导致隐藏时直接跳变——因为移除该类后,过渡属性就没了。立即学习“前端免费学习笔记(深入)”;
- 正确写法:
.modal__overlay { opacity: 0; visibility: hidden; transition: opacity 0.2s ease, visibility 0.2s step-end; } - 配合:
.modal--visible .modal__overlay { opacity: 1; visibility: visible; } - 常见坑:用
display: none替代visibility→display不可过渡,动画失效
多个弹窗共存时,z-index 必须由 block 统一控制
给
.modal__overlay直接写z-index: 9999是自毁行为。不同弹窗类型(confirm、toast、drawer)需要可预测的层叠顺序,且不能互相干扰。- 推荐方案:在
:root中定义 CSS 自定义属性,如--z-dialog: 1000、--z-toast: 900 -
.modal { z-index: var(--z-dialog); },子元素(.modal__overlay、.modal__content)不再设z-index - 关键约束:
.modal__overlay必须用position: fixed; inset: 0;,避免被父级transform创建的新层叠上下文截断
最常被忽略的一点:BEM 不是字符串拼接游戏,
__和--的位置一旦错位(比如写成modal_overlay或modal--overlay),类名就失去语义锚点,后续所有样式联动和 JS 状态管理都会脱钩。 - 正确写法:


















