BEM盲写依赖显式边界而非记忆,需明确样式归属目录、修饰对象及状态可枚举性。Block须对应物理目录,Element不可脱离Block独立存在,Modifier仅表达布尔或有限状态,工具链须配置componentName、禁用多短横与嵌套选择器。

盲写代码不是靠肌肉记忆,而是靠命名规则足够确定、边界足够清晰——BEM 能做到这点,但前提是它被当作约束系统来用,而不是贴在 class 上的装饰标签。
为什么手写 card__title 会突然卡住
你盯着编辑器想补全下一个类名时停顿,往往不是记不住语法,而是不确定当前上下文是否允许写 card__footer--sticky:这个修饰符到底该挂 card 块上,还是挂 card__footer 元素上?有没有已定义的 card--compact 会和它冲突?这些犹豫全来自缺乏显式边界。
- Block 必须对应一个物理目录(如
src/components/card/),所有以card开头的样式只能放这里 - Element 名不能脱离 block 独立存在,
__title永远只出现在card__title中,不会单独叫title - Modifier 只表达状态,不描述样式,
--hover合法,--blue违规(应归入主题系统或 CSS 自定义属性)
stylelint-selector-bem-pattern 怎么配才真能帮你盲写
默认配置下它只校验格式,header__logo 和 logo 都能过,但后者可能是另一个独立 Block,混用就破坏隔离。真正起效要打开三道闸门:
前端设计与 UI/UX 全方位优化专家。覆盖视觉层次、排版系统、色彩理论、响应式布局、交互体验、动画动效、无障碍访问、性能优化八大维度,帮助开发者将普通页面升级为高品质产品级界面。前端设计与 UI/UX 全方位优化专家。覆盖视觉层次、排版系统、色彩理论、响应式布局、交互体验、动画动效、无障碍访问、性能优化八大维度,帮助开发者将普通页面升级为高品质产品级界面。
- 启用
componentName选项,把项目中所有 Block 名(如['card', 'user-avatar', 'search-form'])注册进去 - 设
allowMultipleDashes: false,否则button--primary--loading不报错,而 BEM 明确禁止修饰符链式叠加 - 配合
no-descending-specificity,阻止写.card__header { .card__title { ... } }——这种嵌套会让盲写失效,因为你无法从 HTML 类名反推 CSS 层级
React/Vue 动态类名不拼字符串,用函数封装
手拼 className={`card ${isFolded ? 'card--folded' : ''}`} 表面正确,实则埋雷:变量名改错、条件漏写、大小写不一致(CARD--folded),CSS 就静默失效,调试时得翻三处。
- 统一用
clsx或封装bem('card', { folded: isFolded }),所有输出都基于同一 block 名生成 - 禁止在组件内硬编码带
__或--的字符串,连'card__body'都不行 —— 它必须由函数动态合成 - Vue 的
:class同理::class="[bem('card'), bem('card', { folded: isFolded })]",不是['card', isFolded && 'card--folded']
BEM 的盲写能力不在命名本身,而在它强制你回答三个问题:这个样式属于哪个物理组件目录?它修饰的是块还是块内的某个固定部分?它的变化是否可枚举且不依赖其他状态?答不全,就写不出来 —— 这种“写不出来”,恰恰是工程约束开始生效的信号。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










