直接写 .card .title 危险,因它将样式与dom结构强绑定,易被外部节点意外匹配或受全局.title影响;正确应为.card__title等扁平化独立类名,且修饰符必须依附宿主(如button button--primary),禁止孤立或混搭层级。

为什么直接写 .card .title 是危险的
它把样式和 DOM 结构强绑定。一旦 .card 被嵌套进 .modal 或 .sidebar,.card .title 可能意外匹配到外部节点;更隐蔽的是,别人改了全局 .title 的 margin,你的卡片顶部间距就崩了。.card__title 是独立类名,不依赖父容器是否存在、是否在某一层 DOM 中。
禁止写 .card > .header 或 .card .card__title——前者断链风险高,后者冗余且破坏扁平语义。
所有子元素必须显式声明归属:.card__title、.card__subtitle、.card__footer-action,不能靠结构推导。
button__icon--primary 为什么是错的
双下划线 __ 只表归属,双短横 -- 只表状态,二者不能混搭层级。button__icon--primary 会被解析为“一个叫 icon--primary 的元素”,而你要表达的是“按钮处于 primary 状态时,其图标颜色随之变化”——这属于块级状态,不是图标自身的变体。
正确写法:button--primary(按钮整体状态),再由 CSS 变量或内部规则控制 button__icon 颜色。
若图标真有独立状态(如加载中旋转),才用 button__icon--loading。
绝对禁止 button--primary__icon:修饰符不能挂在元素的修饰符上,BEM 工具会直接忽略。
Block 命名必须可复用,不能是 homepage-hero-banner
过度具体的 Block 名导致无法复用。比如 homepage-hero-banner 写死上下文,后续在产品页用不了;应抽象为 hero-banner,靠组合使用(如 hero-banner--homepage)来表达上下文。
Block 必须语义化且唯一,对应一个可复用的独立组件(如 search-form,不是 form)。
禁止用布局词:section、container、wrapper 非法——它们没有明确职责,后续加 __ 或 -- 会失去上下文。
多单词用 - 连接,不用驼峰或下划线:date-picker ✅,datepicker ❌(歧义),date_picker ❌(违反约定)。
Modifier 必须挂载在 Block 或 Element 上,不能孤立使用
class="button--primary" 不能单独出现。修饰符没有上下文就是语义断裂——没人知道这个 --primary 是按钮、输入框还是弹窗的。它必须依附于宿主存在,否则复用时极易误判。
合法:class="button button--primary"、class="button button__icon button--primary"。
非法:class="button--primary"、class="disabled"(孤立修饰符)。
常见错误:user-card--small ——尺寸是响应式行为,不是固有状态;应配合媒体查询用 user-card--compact 或直接上 @media 控制。
更隐蔽的坑:card__title--large 可以,但 card--featuredtitle--large 是非法结构,编译器不会报错,但人脑会卡住。
最常被忽略的一点:BEM 不是靠“加 __ 和 --”就自动可维护,而是用命名契约把样式所有权钉死在组件上;不按规则写,button__icon 可能被全局 .icon 覆盖,card--dark 可能根本没生效——浏览器不报错,但样式就悄悄失效了。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











