Flex容器类名须体现业务职责(如product-grid),禁用flex-container等暴露实现的命名;子项必须带完整BEM路径(如product-grid__item),禁止泛化类名item;对齐逻辑应写在Block规则中,Modifier需用语义化命名(如--spaced)而非CSS属性映射。

Flex容器类名不能叫flex-container或row
这类名字暴露实现细节,且业务语义全无。换成product-grid、nav-menu或editor-toolbar,HTML里一眼就知道它承载什么功能,而不是“用了Flex”。CSS中写display: flex就够了,技术细节不该挤进类名。
常见错误是定义一个全局.flex工具类,然后到处加:className="flex"。结果改一处,三处崩:card头变横排、modal footer错位、表单按钮组对不齐。BEM不是让你多打几个短横线,是让你把归属关系钉死在类名里。
- ✅ 正确:
<div class="product-grid"></div>,样式只作用于这个块 - ❌ 错误:
<div class="flex-container--centered"></div>,换用Grid后类名就失效,还掩盖了真实模块意图 - ⚠️ 注意:CSS Modules或scoped CSS下,
.flex哪怕局部作用域,也因缺乏上下文而无法追溯用途——你永远不知道它是为撑开卡片头,还是为居中按钮组
justify-content和align-items该写在哪
直接写在Block规则里,不要靠修饰符模拟,更别用margin-left: auto硬凑两端对齐。Flex的对齐逻辑属于容器级职责,不是每个子项都要自己扛。
- ✅ 正确:
.nav-menu { display: flex; justify-content: space-between; align-items: center; },所有nav-menu__item自然生效 - ❌ 错误:给
nav-menu__item单独加margin-left: auto来右推最后一个,既难维护,又违背Flex本意 - ⚠️ 单个项目需特殊对齐?用
align-self+ Modifier:nav-menu__item--align-bottom { align-self: flex-end; },删掉类就回退,默认值不依赖cascade
子项类名必须带完整BEM路径,禁用item或child
看到<div class="item"></div>,你根本不知道它属于哪个模块、能否复用、是否允许单独渲染。Flex子项一旦脱离Block上下文,样式极易错乱,调试时也找不到源头。
立即学习“前端免费学习笔记(深入)”;
- ✅ 正确:
<div class="product-grid"><div class="product-grid__item"></div></div>,CSS写.product-grid__item,不依赖父类选择器 - ❌ 错误:
<div class="product-grid"><div class="item"></div></div>,.item全局污染,后续cart-item、nav-item都可能被覆盖 - ⚠️ 如果
product-grid__item内部还要拆结构(如标题、价格),优先判断是否可独立成块;若只在此处出现且无复用需求,可用product-grid__item-title;若标题样式要复用于详情页,则应拆为product-title独立Block
Modifier不能映射CSS属性,得用业务语义
别写--justify-center或--align-items-flex-end这种纯属性搬运工式修饰符。它们绑定实现,未来换gap或place-items就得全量改类名。
- ✅ 推荐:
button-group--spaced(表示子项等距分布)、card--expanded(表示展开态),语义稳定,实现可替换 - ❌ 禁止:
button-group--justify-between,改布局方式时类名就失去意义 - ⚠️ Modifier必须可开关:删掉
--spaced,布局立刻回退到默认值,不靠fallback或层级覆盖兜底
display: flex兼容性(Chrome 29+已全支持),而是类名没绑定Block导致的样式覆盖、误复用、查不到源头。BEM不是命名格式游戏,是把“谁该用什么规则”这件事,在HTML里钉死。


















