card__header__title是非法命名,因bem仅允许block__element两级结构,三段式命名将card__header误作新block,违背“元素仅属块直系”原则,导致语义断裂、复用困难及dom变动时样式静默失效。

card__header__title 是非法的
不是浏览器报错,而是语义失效——card__header__title 违反 BEM 最基本结构规则:block__element 只允许两级,不能出现第三个 __。它隐含地把 card__header 当作新 Block,但 card__header 本身只是 card 的一个 Element,没有资格承载子 Element。
- DOM 改动后样式静默失效:比如给
card__header外层加个<div class="wrapper">,<code>card__header__title就完全不匹配了 - 无法复用:你没法把这个类名拿到用户页、弹窗或侧边栏里单独使用,它被当前 DOM 路径锁死
- SCSS 中写
&__header { &__title { } }会编译出非法类名,还容易误给card__header加 padding,破坏 Element 的纯展示职责 - 有复用性(比如标题在多个模块都出现)→ 升格为独立 Block:
heading,再组合使用:card__header <heading class="heading--in-card"></heading> - 无复用、仅装饰(如标题旁的小图标)→ 用 Modifier:
card__title card__title--with-icon - 强上下文依赖、一次性场景(如折叠面板里的二级标题)→ 用 State 类:
class="heading is-subheading"或data-context="accordion" - 块可以自由嵌套:
header里放logo和search-form,三者都是独立 Block,类名分别是logo、search-form,不是header__logo - 元素必须直属于块:
menu__item可以出现在nav-menu或dropdown-menu里,但它永远只属于自己的 Block,不能跨层挂靠 - 布局微调允许一层后代选择器(如
.card__header .heading),但前提是.heading是独立 Block;绝不可写.card__header .card__title - 只允许
&__element和&--modifier写法,禁用普通嵌套:.card { .title { } }是错的 - 伪类、媒体查询要用
@at-root提出来,避免生成.card:hover .card__btn这类层级选择器 - 状态类必须手动加到 HTML 上,比如
button class="btn btn--disabled",而不是靠.btn:disabled推导
遇到“元素里的内容”该怎么命名
关键不是看 HTML 嵌套几层,而是问:这个节点有没有独立语义或复用可能?
PigX UI Pro 前端开发指南 - Vue 3 + TypeScript + Element Plus。当用户提到 PigX UI、PigX 前端、lgb-mgui 项目、Vue 3 企业级后台开发、Element Plus 后台开发时使用此技能。
BEM 允许块嵌套,但禁止元素嵌套
HTML 里可以 <header><nav><ul><li></ul></nav></header> 套四层,只要类名归属清晰就行。BEM 真正禁止的是类名随 DOM 层级“滑动”,不是 DOM 本身。
SCSS 里怎么写才不踩坑
Sass 嵌套天然容易产出非 BEM 结构,必须人工约束。
__ 和 --,是每次写新类名前停半秒:这个东西,离开当前父容器还能不能活?如果不能,它就不该有自己的 BEM 名字。










