图标不可单独作为 Block,必须依附功能组件命名如 btn__icon;基础类需声明 display 和 vertical-align,修饰符须正交且仅表达单一维度。

图标不能单独作为 Block,必须依附功能组件命名
直接定义 icon 或 ui-icon 作为 Block 在多数真实项目中是反模式。图标本身没有交互逻辑、不承载业务语义,强行升格为 Block 会导致样式污染、主题无法隔离、PurgeCSS 误删动态类(如 icon--loading)。只有当图标被三个以上不同上下文复用(按钮、表单项、弹窗标题),且需独立控制状态/动画/点击行为时,才考虑升格为 Block;否则一律用功能组件下的 Element 命名。
-
btn__icon、form-item__icon、nav-link__icon是合法且推荐的写法 - 禁止:
<i class="icon icon--24 icon--primary"></i>(裸奔 Block,无归属) - 正确:
<button class="btn"><i class="btn__icon btn__icon--sm btn__icon--success"></i>提交</button>
基础类必须声明 display 和 vertical-align,否则修饰符失效
btn__icon--rotate 不转、btn__icon--sm 对齐错乱,大概率是因为图标元素是 display: inline,而 transform 和尺寸缩放对纯内联元素默认不触发重排或基线计算。这不是 BEM 命名问题,是渲染行为缺失。
- 基础类
btn__icon必须包含:display: inline-block、font-size: 1rem(字体图标)或width/height(SVG)、vertical-align: -0.125em - 修饰符只负责状态:比如
btn__icon--rotate只写transform: rotate(90deg),不重复声明display - 若用 SVG 内联,确保
<path fill="currentColor"></path>,颜色由btn__icon--error控制color即可
尺寸、颜色、状态修饰符必须正交,不可混写
一个修饰符只表达一个维度。混写如 btn__icon--sm-error-loading 看似省事,实则破坏可组合性,也违背 BEM 修饰符单一职责原则——它让类名既管尺寸、又管主题、还管行为,后续任何一项变更都可能牵一发而动全身。
- 尺寸类:
btn__icon--sm、btn__icon--lg→ 只改font-size或width/height - 颜色类:
btn__icon--primary、btn__icon--danger→ 只设color/fill,基于设计系统变量(如var(--color-success)) - 状态类:
btn__icon--loading、btn__icon--success→ 只负责旋转、路径切换或visibility,不碰尺寸或色值
伪元素插入图标时,颜色和 content 必须挂载到真实元素上
如果用 ::before 插入字体图标(如 content: "\e901"),修饰符不能只作用于虚拟节点。BEM 不约束伪元素本身,但要求所有视觉变体必须通过真实存在的 Block 或 Element 类来触发。
立即学习“前端免费学习笔记(深入)”;
- 错误:
.btn__icon--error::before { color: #f00; }(没保证.btn__icon存在且已设font-family) - 正确:基础类
.btn__icon已声明font-family: 'iconfont';修饰符.btn__icon--error同时作用于元素和伪元素:.btn__icon--error, .btn__icon--error::before { color: var(--color-error); } -
content值不进 BEM 命名——它是样式实现细节,不是结构语义
btn--loading 状态,btn__icon--loading 必须同步生效,且这个修饰符得能被 PurgeCSS 安全保留——这意味着它必须在 HTML 中静态存在,或通过工具链显式声明,不能靠 JS 动态拼接。


















