模态框的 block 名应定为 dialog,避免与 notification-modal、confirm-modal 及 ant-modal 冲突;必须语义明确、中性且复用边界清晰,禁止 modal__content、dialog-modal 等错误写法,尺寸和位置修饰符均须作用于 .dialog 本身。

模态框的 Block 名怎么定才不和已有组件冲突
直接叫 modal 是高危操作——项目里早有 notification-modal、confirm-modal,甚至第三方库注入了 ant-modal。BEM 要求 Block 必须语义明确且具备复用边界,所以推荐用 dialog 作为基础 Block 名:它比 modal 更中性(不暗示“模态”交互逻辑),也避开了 Ant Design、Element Plus 等库的命名前缀。
常见错误:
- 写成
modal__content却在 HTML 里套了<modal>...</modal>(React 组件名 ≠ Block 名) - 用
popup或overlay当 Block,结果和 tooltip、dropdown 的样式层叠优先级打架
实操建议:
- 所有模态类名以
dialog开头:dialog、dialog__header、dialog--large - 若需区分用途,加语义后缀而非前缀:
dialog--confirm✅,confirm-dialog❌(破坏 block-first 原则) - 禁止出现
dialog-modal或modal-dialog这类嵌套式 Block 名
尺寸修饰符(--small / --large)该挂在哪一级
尺寸是状态,不是视觉描述,必须作用于 Block 本身,而不是某个 Element。写成 dialog__body--large 是错的:body 的尺寸由 dialog 容器控制,单独放大 body 会导致 padding 错位、按钮溢出等布局断裂。
正确结构只有一种:dialog--small、dialog--medium、dialog--large。它们应直接控制整个 .dialog 的 max-width、padding 和 font-size。
为什么不能用 --size-small 这种带前缀的写法?
- BEM 修饰符值必须原子化、可枚举,
--small比--size-small更短、更易读、更易被 JS 切换(classList.toggle('dialog--small')) - 如果未来要支持主题色尺寸联动(比如 dark theme 下 --large 自动加 8px),统一挂 Block 上才便于用 CSS @layer 控制层叠顺序
注意:不要把响应式断点塞进修饰符,dialog--mobile 是反模式。媒体查询应收口在 dialog.css 文件末尾,包裹 .dialog--large 的规则即可。
位置修饰符(--top-left / --center)为什么不能写成 dialog__overlay--center
位置控制的是整个模态框的呈现锚点,不是 overlay 层的定位方式。dialog__overlay 只负责遮罩层(fixed + z-index),它的 position 属性不该承担“让 dialog 居中”的职责——那属于 .dialog 自身的 transform 或 grid layout 逻辑。
所以 --center、--top-right、--bottom-full 全部只能挂在 .dialog 上:
.dialog {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
<p>.dialog--top-right {
top: 1rem;
left: auto;
right: 1rem;
transform: none;
}
</p>
容易踩的坑:
- 给
dialog__content加--center,结果 content 居中了但 overlay 还盖不满全屏 - 用
dialog--position-center这种冗余前缀,违反修饰符“简短可枚举”原则 - 在 JS 中手动计算 top/left 并写内联 style,绕过 BEM 修饰符体系,导致无法用 CSS 动画或媒体查询接管
如何让 dialog--large 和 dialog__footer--compact 同时生效又不冲突
它们根本不在同一层级:一个作用于 Block,一个作用于 Element,BEM 允许并行存在。关键在于 CSS 规则的书写顺序和 specificity 控制。
必须遵守的两条铁律:
- 所有
.dialog--*规则写在.dialog__*规则之前(@layer base > components) -
.dialog__footer--compact只能调整 footer 内部间距,不能重置.dialog--large设定的 max-width 或 padding
示例安全写法:
.dialog--large {
max-width: 800px;
padding: 2rem;
}
<p>.dialog__footer {
padding: 1rem 2rem;
}</p><p>.dialog__footer--compact {
padding: 0.5rem 1rem; /<em> 只微调,不碰外层容器 </em>/
}
</p>
最常被忽略的点:当使用 CSS-in-JS 或 CSS Modules 时,dialog--large 和 dialog__footer--compact 很可能被编译成不同哈希类名,导致层叠失效。此时必须用 @layer 显式声明层级,或改用 CSS Modules 的 :global(.dialog--large) 手动拉平作用域。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











