BEM卡片组件高复用的关键在于:card必须作为独立Block存在,子元素严格使用card__前缀,修饰符仅挂载于card根上;否则复制即失效。

直接说结论:BEM 卡片组件能否高复用,不取决于你写了多少类名,而在于 card 是否真正作为独立 Block 存在、所有子元素是否严格绑定 card__ 前缀、修饰符是否只挂载在 card 根上——漏掉任一环,复制到新页面就失效。
为什么 .card .title 一粘贴就失灵
浏览器匹配选择器是从右往左的:.card .title 实际在找「任意父级含 card 类的 title 元素」。一旦新项目结构是 <section class="product-card"><h3 class="title"></h3></section>,样式立刻断掉。
更麻烦的是继承污染:font-size: 0.875rem 这种外层设置会悄无声息地影响 .title,但你在 CSS 里根本没声明它,调试时像在捉迷藏。
而 .card__title 不依赖父容器是否存在,只要 HTML 里写了这个类,样式就生效——它靠命名显式声明“我只属于 card”,不是靠 DOM 层级“猜”关系。
立即学习“前端免费学习笔记(深入)”;
- 禁止松散组合:
.card .card__title是冗余写法,.card__title本身已带上下文 - 别用泛化类名迁移:
.title或.header在新项目里大概率语义漂移,改一个地方,其他页面跟着错 - 根元素必须存在:
<div class="card__title"></div>单独出现无效;必须有<div class="card">...<div class="card__title"></div>...</div>
card__header / card__body / card__footer 怎么命名才不翻车
Header 不是 “head”,body 不是 “content”,footer 不是 “actions”——BEM 要求 Element 名准确反映职能,不能模糊或泛化。
card__header 必须专用于顶部区域(标题 + 副标题 + 时间戳),card__body 严格包裹主要内容,card__footer 只放底部动作(“查看详情”)或状态标签(“已发布”)。
- 禁用缩写:
card__head❌、card__main❌、card__content❌ —— 它们无法表达在卡片中的真实角色 - 避免嵌套元素:
card__header__icon违规;图标应作为card__header的一部分,用伪元素或内联 SVG 实现 - 结构即语义:如果设计稿里某个区域同时含标题和操作按钮,它就是
card__header,不是两个分离的card__title和card__action
card--large / card--inverted 等修饰符该挂在哪
修饰符必须依附于 Block 或 Element,不能单独存在;且要作用在正确层级上——card--large 控制整体缩放,card__title--highlighted 只影响标题样式。
常见错误是把状态类挂错位置:.card__title--large 表示“标题变大”,但实际需求往往是整个卡片变大(包括 padding、字体、间距同步缩放),这就破坏了 Modifier 应描述组件整体状态的原则。
- 合法写法:
class="card card--large"、class="card card__title card__title--highlighted" - 非法写法:
class="card--large"(缺card根)、class="card__title--large"(应由card--large统一控制) - 不要为纯视觉差异新建 Block:
card--horizontal合理(影响多子元素结构逻辑),card--blue❌(颜色应由主题系统或 utility class 控制)
card__body 高度自适应却不限高,怎么写才稳
设 height: 100% 不行——它依赖父元素有明确高度,而卡片常嵌在 flex/grid 容器中,父级高度可能是 auto。
真正可控的方式是靠父容器布局上下文约束:card 设 display: flex; flex-direction: column,再用 flex: 1 + min-height: 0 让 card__body 填满剩余空间。
-
card__header和card__footer保持默认flex-shrink: 0(不压缩) -
card__body必须加min-height: 0—— 否则它会无视父容器剩余空间,强行按内容撑高 - 如需内部滚动,只在
card__body上设overflow-y: auto,不要给card设固定高 - 响应式字体建议用
clamp(1.125rem, 4vw, 1.5rem),比媒体查询断点更贴合阅读逻辑
最容易被忽略的一点:BEM 不是命名游戏,而是边界声明。当你写下 card__avatar,你同时承诺了两件事——它只属于 card 上下文,且不会因外部 font-size 或 display 规则意外变形。这点一旦松动,复用性就从根上瓦解。


















