新手应先用BEM固定结构并加团队前缀(如nc-button),再逐步增强语义化;直接写.header或.btn必然导致全局样式冲突,因CSS无作用域,同名类会按加载顺序覆盖,且难以溯源。

直接说结论:新手别从“语义化”开始,先用 BEM 固定结构,再加业务前缀,否则三个月后 class 会满屏冲突、改一个崩一片。
为什么一上来就写 .header 或 .btn 是高危操作
这些名字看着合理,但实际在工程中等于没命名——Ant Design、Element Plus、旧项目、甚至同事写的 reset.css 都可能定义同名 class。浏览器只认类名字符串,不认你心里想的“这个 btn 是我写的”。一旦发生覆盖,DevTools 里看到的是样式被删了,但源码里根本找不到谁动的手。
常见错误现象:
- 本地开发正常,CI 构建后按钮突然变宽 → 某个全局
.btn规则被意外引入 - 给
.card加了阴影,结果所有页面的卡片都带阴影 →.card在 layout.css 里被提前定义过 - JS 动态加
is-active,但其他模块也有同名状态类,样式互相打架
新手可立即落地的 BEM + 前缀组合写法
不是“学完 BEM 再用”,而是直接套模板起步,降低决策成本:
立即学习“前端免费学习笔记(深入)”;
- Block 名必须带团队/产品前缀:
nc-button、ds-input、dash-chart-bar(nc= your team,ds= design system) - Element 用双下划线:
nc-button__icon、nc-button__label—— 只能是 Block 的直接子节点,不能出现nc-button__content__title - Modifier 用双短横:
nc-button--disabled、nc-button--loading—— 加在 Block 上,不是加在 Element 上 - JS 钩子统一用
js-前缀:js-modal-trigger,和样式类完全隔离,避免误删
示例 HTML:
<button class="nc-button nc-button--primary js-modal-trigger"> <span class="nc-button__icon"></span> <span class="nc-button__label">提交</span> </button>
哪些命名习惯会让后续维护爆炸
这些坑新手几乎必踩,且 CI 不报错、测试不覆盖、上线才暴露:
- 用颜色/尺寸/位置命名:
.red-btn、.w-100、.left-sidebar—— 设计改版后,类名和样式意义脱钩,没人敢删 - 缩写随意:
.hdr、.ctn、.btn-sml—— 三个月后自己都看不懂,更别说协作 - 在 JS 里硬拼 class 字符串:
el.className = `nc-button nc-button--${status}`—— 容易漏空格、错连字符、大小写不一致 - 把 wrapper div 当语义节点:
<div class="card__content"><h3 class="card__content__title"></h3></div>——card__content如果不封装逻辑、不复用,它就只是个无意义容器,不该有 class
真正关键但常被跳过的一步:工具链拦截
BEM 写得再标准,只要没进检查流程,就会退化。建议立刻接入:
- ESLint 插件
stylelint-selector-bem-pattern,校验 class 是否符合block__element--modifier格式 - CI 脚本里 grep 禁用词:
grep -r "\.btn\|\.header\|\.card" src/,发现即 fail - PR 模板强制填写:
【Class 命名依据】本次新增 class 是否已带前缀?是否与现有 Block 冲突?
最常被忽略的点:Block 名一旦定错,所有 __element 和 --modifier 都跟着错;而这类错误在本地开发、单元测试、甚至 E2E 中都完全不可见,只有当两个组件库同时加载、或主题切换时,才会在某个深夜的灰度环境里突然失效。


















