必须优先识别并隔离.btn、.nav、.sidebar等泛化类名,因其在旧项目中实际充当JS硬编码绑定和高权重CSS覆盖的隐式接口,直接全局替换将导致样式崩坏与JS断裂。

哪些类名必须先停手,别碰
直接全局搜索替换 .btn、.nav、.card 这类泛化名,90% 会触发样式崩坏和 JS 断裂。它们在旧项目里不是“样式类”,而是隐式接口:JS 可能正用 document.querySelector('.btn') 绑定事件,CSS 可能靠 #main .content .item a:hover 这种高权重规则强行覆盖。先用这条命令筛出所有硬编码点:
grep -r "document\.querySelector\(['\"].*\.[a-z]\+['\"]\)" src/ --include="*.js"结果里的每个类名,都不能删,只能加 BEM 别名过渡。
HTML 不动结构,怎么安全加 BEM 类名
老项目 DOM 嵌套深、语义乱,硬拆结构会牵连表单校验、事件委托和 SSR 渲染。务实做法是「语义映射」:
- 原代码:
<div class="form"><input></div>→ 改为:<div class="login-form"><input class="login-form__input"></div> - CSS 中立刻删掉所有孤立的
.input、.error规则,只保留.login-form__input和.login-form__input--error - 禁止写
.login-form .input这类后代选择器——它默认父容器永不变更,而 BEM 的契约是“删掉login-form,子元素仍能渲染”
@layer 和加载顺序怎么配才不被旧 CSS 压住
新写的 .button__text 样式还是被 #header .nav li a:hover 覆盖?问题不在命名,在层叠逻辑没理清:
-
<link>必须严格位于旧 CSS 之后(哪怕只是逻辑上后加载) - 用
@layer显式分层:@layer legacy { /* 旧规则 */ }+@layer bem { /* 新 BEM 规则 */ },现代浏览器按层覆盖 - 对强污染的旧容器(如
<header class="legacy-header"></header>),可在其 CSS 开头加.legacy-header { all: unset; }(慎用,仅限紧急场景) - 新 BEM 组件必须显式重置基础样式:
box-sizing: border-box、margin: 0、padding: 0,避免继承旧全局重置的副作用
Block 名怎么起才不会三年后没人敢动
Block 名不是加前缀,而是定义归属边界。起错名字,后续迭代就卡死:
-
card❌ —— 全局冲突高,别人写.card__title时根本不知道你在哪个业务域 -
product-card✅ —— 明确归属,和user-card、cart-card天然隔离 -
card--featured✅ —— Modifier 表达视觉变体;card--loading❌ —— 这是 JS 状态,不该由 CSS 类控制 -
product-card__footer__copyright❌ —— 超过两级 element,说明copyright已具备独立 Block 特征,应拆为copyright-block - 历史遗留的
.clearfix、.hidden,统一迁移到u-clearfix、u-hidden,和 BEM 业务类严格分离
立即学习“前端免费学习笔记(深入)”;


















