不能直接用.card__header替代.card .card-header,因为.card-header是bootstrap官方语义类名,承载padding、border-top、font-weight等关键样式;而.card__header是bem自定义类,不在bootstrap选择器范围内,无任何默认样式,必须与.card等基础类共存以确保样式生效。

为什么不能直接用 .card__header 替代 .card .card-header
因为 Bootstrap 的样式规则全部依赖语义类名触发,.card-header 这个类本身才携带 padding、border-top、font-weight 等关键样式;而 .card__header 是一个全新类名,不在任何 Bootstrap 选择器范围内,浏览器根本不会给它应用任何基础样式。常见现象是:DOM 中写了 <div class="card__header">,但 DevTools 里查不到生效的 CSS 规则,整个区域塌陷、无间距、无字体加粗。
<p>必须共存两类 class:<code><div class="card card__header"> 或 <code><div class="card user-card"><div class="card__header user-card__header">。BEM 类名不代理、不模拟、不继承 Bootstrap 行为,它只负责业务语义隔离。
<h3>如何组织 SCSS 文件避免变量冲突和编译报错</h3>
<p>Bootstrap 的 <code>_variables.scss 和你的自定义变量必须严格按顺序导入,否则 Sass 会报 Undefined variable。错误做法是在每个 BEM 组件文件里重复 @import "bootstrap/scss/variables" —— 变量已在顶层定义,重复引入会覆盖或报错。
- 入口 SCSS(如
app.scss)中,顺序固定:@import "bootstrap/scss/functions"→@import "bootstrap/scss/variables"→@import "custom-variables"→@import "bem/user-card" - 所有自定义变量必须加命名空间前缀:
$user-card-spacing-sm、$user-card-border-radius,禁止直接重写$primary等全局变量 - BEM 组件 SCSS 文件(如
_user-card.scss)里只写样式逻辑,不@import任何 Bootstrap 源文件,只用已导入的函数和变量
怎么写修饰符才不会导致状态类静默失效
BEM 修饰符不是自由拼接的字符串,它必须绑定到具体 Block 或 Element,且值需校验有效性。JS 动态生成类名时,若修饰符为空或非法,会产出像 user-card__button-- 这样的无效类,CSS 规则完全不匹配,样式静默丢失,极难排查。
- 修饰符必须成对出现:写
.user-card__button--disabled,就得有对应 CSS 规则,不能只靠 JS 加类而无样式支撑 - 禁止修饰符脱离上下文单独使用:
.user-card--disabled合理,.disabled❌(语义断裂,无法定位来源) - JS 拼接前做空值判断:
const modifier = status ? `--${status}` : '',避免生成--尾缀 - 修饰符描述的是“状态”或“变体”,不是“样式效果”:用
.user-card--compact,而不是.user-card--no-padding
如何防止 Bootstrap 高特异性规则覆盖你的 BEM 样式
Bootstrap 大量使用复合选择器,例如 button.btn.btn-primary 的 specificity 是 0,0,3,0,远高于单个 .user-btn--loading(0,0,1,0)。仅靠加载顺序无法稳定覆盖,容易在重构后突然失效。
- 提升你自己的选择器权重:用
.user-btn.user-btn--loading而非.user-btn--loading - 在 SCSS 中用
@extend复用 Bootstrap 占位符(如%btn),前提是项目编译源码且启用占位符输出 - 禁用不用的 Bootstrap 模块:在
custom-variables.scss中设$enable-button-variants: false,减少干扰规则数量 -
!important仅用于基础设施级契约(如box-sizing: border-box !important),业务层修饰符严禁滥用
.homepage-user-card 这种过度具体的命名,半年后就变成技术债。











