BEM 命名须用作用域前缀如 dash-chart,元素为 bar-chart__axis-label 等一级结构,修饰符如 --loading 仅依附块或元素,响应式用 bar-chart--mobile 统一控制。

图表容器 class 命名必须带明确作用域前缀
直接用 .chart 或 .graph 会导致样式污染,尤其在微前端或组件库场景下极易被覆盖或误匹配。BEM 要求块名(Block)反映功能+上下文,比如项目叫「dash」,就该用 dash-chart,而不是泛泛的 chart。
常见错误现象:.chart .title 在页面其他地方也用了 .chart,结果仪表盘标题字体被报表模块的样式意外改掉。
- 块名必须唯一且可识别来源,推荐格式:
[project]-[component]-[type],例如dash-chart-bar、dash-chart-line - 避免纯语义化命名(如
data-visual),它无法定位到具体组件实例 - 如果图表是封装好的 React/Vue 组件,块名应与组件名对齐,比如组件叫
BarChart,块名就是bar-chart
元素 class 必须严格遵循 block__element 格式,不嵌套层级
BEM 不允许写 bar-chart__axis__label 这种三层结构——__label 已经是轴的子元素,但轴本身不是独立块,它只是 bar-chart 的一部分。正确做法是把所有直属于图表的视觉单元都作为一级元素。
使用场景:你要给坐标轴上的刻度文字加样式,但它和图例、标题一样,都是图表的直属子元素,而非“轴的子元素”。
立即学习“前端免费学习笔记(深入)”;
- 正确:
bar-chart__axis-label、bar-chart__legend-item、bar-chart__tooltip-content - 错误:
bar-chart__axis__label(多余下划线)、bar-chart__axis-label-text(过度细分,除非真有多个文本变体需独立控制) - 性能影响:多一层类名解析不会拖慢渲染,但会显著增加 CSS 选择器权重和维护成本,尤其当需要覆盖时得写
.bar-chart.bar-chart--dark .bar-chart__axis-label这类长链
修饰符 class 必须绑定到块或元素上,且只表达状态/变体
--loading、--error、--horizontal 这类修饰符不是独立存在,它必须依附于某个块或元素,否则语义断裂。比如 .bar-chart--loading 表示整个图表处于加载态;而 .bar-chart__legend--hidden 表示图例区域被隐藏——两者作用目标不同,不能混用。
容易踩的坑:有人写 .chart--small 却没定义对应块名 chart,导致样式孤立、无法复用;或者把颜色值当修饰符,比如 --blue,这违反 BEM 原则——颜色是实现细节,不是业务状态。
- 修饰符只用于描述行为或外观变体:
--stacked、--with-animation、--compact - 禁止用修饰符控制具体样式值:
--font-size-12、--bg-#007bff—— 这些该交给 CSS 自定义属性或设计系统 token 管理 - React 中建议通过
className={`${baseClass}${isDark ? ' ' + baseClass + '--dark' : ''}`}拼接,而非用第三方 class 工具隐式处理,避免调试时找不到来源
响应式断点必须收口到块级修饰符,不散落在元素内部
图表在移动端常需折叠图例、压缩间距、切换为滚动式 X 轴。这些变化是整体行为切换,不是某个标签或轴单独调整。把 @media 写在 .bar-chart__label 里,等于把响应逻辑耦合进元素层,后续想统一调整断点位置或新增 breakpoint 就得全局搜改。
性能影响:CSS 媒体查询本身无开销,但分散书写会让打包后 CSS 体积增大、缓存失效更频繁;更重要的是,它让“图表在小屏下怎么表现”这个业务规则变得不可见、不可配置。
- 统一用块级修饰符承接响应逻辑:
bar-chart--mobile、bar-chart--touch - 对应 CSS 中写
@media (max-width: 480px) { .bar-chart--mobile { ... } },所有适配样式都在这个修饰符下组织 - Vue/React 中可根据
window.innerWidth或useMediaQuery动态添加该修饰符,方便测试和模拟
真正难的不是写对 BEM,而是每次加一个新 class 时,得判断它属于块、元素还是修饰符——这个决策一旦错,后面所有人改起来都像在解耦一段坏味道代码。最常被忽略的,是把本该属于块的状态(比如 --empty)偷偷塞进某个元素 class 里,结果空状态样式死活不生效,因为父块根本没加那个修饰符。


















