弹窗多层结构须用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 必须加在根节点上
状态修饰符作用位置错了,整个动画和交互就会断裂。它不是描述某个子元素的外观,而是声明“这个弹窗组件当前处于可见状态”。
- 正确:
,所有子元素通过
.modal--visible .modal__overlay 等选择器响应
- 错误:
→ 遮罩显示了,但
.modal__content 还卡在
transform: translateY(100%)
- 更错:
→ 语法非法,BEM 不允许修饰符出现在 element 名前
transition 必须定义在基础类里,不能塞进 --visible
把 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 状态管理都会脱钩。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!