bem禁止card__header__title这类三层命名,因其违反“元素仅属块直系”的核心规则;正确做法是将title设为独立block(如heading)或用modifier(heading--in-card-header)及父级微调布局。

Element不能嵌套Element,根本不存在“怎么写”的问题
BEM规范里card__header__title这类写法不是“写法不推荐”,而是**语法非法**——它直接违反BEM对元素(Element)的定义:必须是Block的直属子节点。浏览器不会报错,但CSS选择器会失去语义锚点,组件无法独立复用,SCSS编译后生成的类名也脱离协作契约。
为什么card__header__title在SCSS里一写就埋雷
常见错误是这样写:
.card {
&__header {
&__title { color: #333; }
}
}
编译结果是.card__header__title,表面看“结构清晰”,实际带来三重问题:
- 类名本身不合法,破坏BEM原子性,工具链(如stylelint-bem)会直接报错
-
&__header被误当作容器块,开发者可能给它加padding或display: flex,结果污染card__header作为纯Element的职责 - 一旦把
title抽成独立组件(比如复用到list-item里),所有相关样式、JS逻辑、测试用例全得重写
DOM有三层嵌套,HTML和CSS该怎么配对
真实DOM可以深,但类名归属必须扁平。关键不是“删div”,而是让每个视觉单元拥有自己的Block身份:
- 若
title在多个上下文复用(如card header、modal header、sidebar section),就定义独立Block:heading,再用Modifier表达上下文:heading--in-card-header - 若
title几乎只出现在card header中,且样式强依赖位置(比如需要紧贴header下边框),改用父级微调:.card__header .heading { margin-bottom: 8px; }——这种嵌套仅限一层,且只用于布局偏移,不定义字体、颜色等核心样式 - 避免用
data-属性做样式钩子,除非是临时状态(如is-collapsed),长期样式应走Modifier或独立Block
什么时候真该拆出新Block而不是硬套__
判断标准很直白:这个元素是否具备「独立功能、可单独测试、能脱离当前父容器存在」?
-
card__body__button-group→ 必须拆,button-group是通用控件,有自己的交互逻辑和变体(primary / secondary / icon-only) -
table__row__cell__icon→ 必须拆,icon是基础原子组件,table-cell只负责布局容器,不定义图标行为 -
form-field__label__required-mark→ 可不拆,required-mark无交互、无变体、无复用场景,用form-field__label::after伪元素更轻量
真正容易被忽略的是:BEM的“扁平”不是指DOM要扁,而是**样式作用域必须扁平**。哪怕HTML里套了五层div,只要每个视觉单元都有明确Block身份,CSS就不会失控。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











