设计系统与bem真正落地的核心在于「设计原子」与「bem块名」严格对齐:button组件对应.button块,color-primary变量映射到.button--primary修饰符,禁止--blue等表现型命名,确保语义统一、变量可维护、类名可搜索。

设计系统不是把颜色变量扔进 :root 就算落地了,BEM 也不是加几个下划线就叫模块化。真正能跑通的落地,核心在于「设计原子」和「BEM 块名」必须对齐,否则变量管颜色、BEM 管结构,两边各写各的,最后样式还是散装的。
设计系统变量怎么映射到 BEM 修饰符上
设计系统里定义的 color-primary、spacing-md 这些变量,不能只在 CSS 里用 var(--color-primary) 填充,得让它们和 BEM 的语义挂钩。比如按钮的主色状态,应该对应 .button--primary,而不是 .button--blue。
常见错误现象:.button--blue 在换品牌色时要全局搜索替换;而 .button--primary 只需改一次变量值,所有用到它的地方自动同步。
实操建议:
- 修饰符名必须是有限枚举、业务语义明确的,如
--primary、--outline、--compact,禁止出现--bg-blue、--pad-16这类表现型命名 - SCSS 中用
@each把设计系统中的状态映射为 BEM 类:@each $state, $color in $button-states { .button--#{$state} { background-color: map-get($colors, $color); } } - 变量名和修饰符名保持可推导关系,比如
$colors.primary→.button--primary,避免中间多一层翻译
组件级 BEM 块名如何与设计系统原子对齐
设计系统里的「Button」原子,必须和前端的 .button 块严格一一对应。如果设计稿标注“Primary Button”,开发却写了 .btn--primary,那整个设计系统就断在了命名层。
容易踩的坑:
- 块名大小写不一致:设计系统写
Button,代码写.button没问题,但写成.Btn或.BUTTON就破坏了映射关系 - 块名带冗余前缀:设计系统定义的是「Tag」组件,代码却写成
.filter-tag,导致无法复用通用tag样式逻辑 - 同一原子多个块名:比如「Badge」在用户页叫
.user-badge,在通知页叫.notify-badge,等于把一个原子拆成了两个维护单元
实操建议:块名必须小写、短横线分隔、与设计系统组件名完全可映射,例如 AvatarGroup → .avatar-group,FormLabel → .form-label。
响应式、主题、状态这三类修饰符怎么共存不打架
一个按钮可能同时是 .button--primary(状态)、.button--mobile(响应式)、.button--dark(主题),三者叠加时,CSS 规则不能互相覆盖或依赖顺序。
使用场景:中后台系统常需支持暗色模式 + 移动端折叠 + 按钮加载态,这时候修饰符的职责边界必须清晰。
实操建议:
- 响应式修饰符只控制布局相关属性(
width、flex-direction),不碰颜色、边框等表现 - 主题修饰符只控制调色板相关变量(
background、color、border-color),不改尺寸或圆角 - 状态修饰符只控制交互反馈(
cursor、opacity、pointer-events),不参与布局或主题 - 禁止写
.button--primary--dark这种复合修饰符,它既不可读,也无法被 PurgeCSS 安全保留
为什么 CSS Modules + BEM 还是会漏样式
用了 CSS Modules,类名自动哈希,但 .button--loading 这种动态添加的修饰符,构建时很可能被 PurgeCSS 当作“未使用”删掉——因为 JS 里是字符串拼接,工具扫描不到。
性能 / 兼容性影响:PurgeCSS 默认只识别 HTML 和模板里的静态类名,JS 中通过 classList.add('button--loading') 添加的类,不会触发保留逻辑。
实操建议:
- 在 PurgeCSS 配置中显式加入 safelist:
safelist: [ /button--(primary|loading|disabled)/, /form-field--(invalid|success)/ ]
- React/Vue 中避免硬编码类名,改用常量对象集中管理:
const BUTTON_MODIFIERS = { primary: 'button--primary', loading: 'button--loading' }; - 测试环节必须检查 DevTools Elements 面板,确认动态类名真实存在于 DOM 上,而不是只在 JS 变量里存在
BEM 和设计系统真正咬合住的那个点,不在命名格式,而在「谁负责定义变体」——设计系统定语义,BEM 定结构,CSS 变量定表现,三者缺一不可,且不能越界。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











