组件自身不得设置外部间距,所有跨组件距离必须由父容器通过语义化修饰符统一声明,这是BEM隔离原则的硬性要求;子组件写margin会导致复用、主题切换和响应式失控,正确做法是父容器用意图明确的修饰符(如\_card-then-button)绑定CSS变量控制间距。

组件自身不负责外部间距,所有跨组件距离必须由父容器用语义化修饰符统一声明。这不是风格偏好,而是BEM隔离原则的硬性要求——一旦子组件写了 margin,复用、主题切换、响应式调整就全失控。
为什么不能在 Block 内写 margin-top/margin-bottom
常见错误现象:.card 自己加了 margin-bottom: 1rem,.button 又加 margin-top: 0.5rem,两者相邻时实际间距变成 1.5rem,且无法被父级覆盖或重置。
- 父子 margin 塌陷会进一步干扰布局,尤其在 flex/grid 容器中与
gap共存时行为不可预测 - 组件挪到模态框、侧边栏等新上下文后,这段
margin往往变成多余空白 - 暗色模式或缩放字号时,硬编码值(如
1rem)无法随 CSS 变量自动适配
正确做法:用父级 Block 的修饰符声明布局意图
比如两个组件 .card 和 .button 需要垂直间隔,应由它们共同的父容器(如 .form-layout)通过修饰符表达语义:
.form-layout__section_card-then-button { margin-bottom: var(--space-m); }
- 修饰符名必须体现意图(
_card-then-button),而非数值(_mb-16)或方向(_margin-bottom) - CSS 实现必须绑定变量:
margin-bottom: var(--space-m),确保主题、DPR、缩放一致生效 - 禁止修饰符叠加相反方向,如同时加
_margin-top-s和_margin-bottom-m—— 层叠规则会让两者都生效,不是“取最大”
Flex/Grid 容器里特别注意 gap 和 margin 别混用
当父容器是 display: flex 或 display: grid 时,给子组件加 margin-right 或 margin-bottom 是高危操作。
- 和
gap同时存在时,浏览器渲染行为在 Safari、旧版 Chrome 中不一致 - 子组件若自带
margin,会导致gap失效或间距翻倍 - 正确解法:移除所有子组件的
margin,改用父容器的gap+ 语义修饰符控制整体节奏,例如.list--spaced设gap: var(--space-md)
最易被忽略的一点:修饰符命名是否真的可读、可维护。写 .layout__area_margin-bottom-l 看似合规,但如果团队没人能说清 _margin-bottom-l 是指“下方留大空”,还是“左侧有 bottom margin”,那这个修饰符就已经失效了——BEM 的语义性不在语法,而在所有人对命名逻辑的共识。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











