直接用 .icon--rotate 不生效是因为图标字体默认为 inline 元素,transform 需配合 display: inline-block 才触发;bem 仅规范命名,不解决渲染逻辑。

直接用 .icon--rotate 不生效,不是 BEM 写错了,而是没处理图标字体的 display 行为;BEM 本身不解决渲染逻辑,只管类名归属和语义。
为什么 .icon--rotate 加了也不转
图标字体(如 Iconfont、Font Awesome)本质是 <i></i> 或 <span></span> 内联元素,transform: rotate() 默认对 display: inline 元素不触发重排。BEM 类名再规范,也救不了缺失的 display 声明。
- 错误写法:
.icon--rotate { transform: rotate(90deg); }—— 没设display,样式被浏览器忽略 - 正确写法:
.icon--rotate { display: inline-block; transform: rotate(90deg); } - 更稳妥做法:在基础类
.icon就统一设display: inline-block,所有修饰符只管状态,不重复声明布局属性
.icon__svg 还是 .icon--svg?别混淆 Element 和 Modifier
图标如果是内联 SVG,它不是“图标块的子节点”,而是“图标的一种实现方式”——属于变体,不是结构组成部分。所以:
-
.icon--svg合理:表示“用 SVG 实现的图标”,是.icon的一种渲染变体 -
.icon__svg错误:暗示 SVG 是 icon 块的固有子元素(比如<i class="icon"><svg class="icon__svg"></svg></i>),但实际项目中 SVG 往往直接替换标签,不存在嵌套 DOM 关系 - 同理:
.icon--font可用于区分字体图标,.icon--sprite用于雪碧图,都属 Modifier 层级
尺寸和旋转修饰符能叠加吗?顺序要不要紧
能叠加,CSS 层叠规则保证样式合并生效;顺序不影响最终效果,但影响可读性。
- 推荐顺序:
icon icon--size-lg icon--rotate—— 先定基础形态(size),再加行为/状态(rotate),符合人眼阅读习惯 - 避免
icon icon--rotate icon--size-lg:虽然渲染一样,但读代码时得反向推导意图 - 注意冲突点:如果
.icon--size-lg设了font-size,而.icon--rotate也设了font-size,后者会覆盖前者 —— 所以修饰符之间必须职责分明,一个管尺寸,一个管变换,不越界
如何让 BEM 类名真正成为“接口”,而不是又一套魔法字符串
BEM 类名要变成可维护的接口,关键不是命名多漂亮,而是让所有使用点都收敛到同一来源。
- 在 SCSS 中定义统一变量:
$icon-block: "icon";,然后用#{$icon-block}--rotate生成选择器,避免硬编码 - Vue/React 组件里不手拼:
className={clsx(iconBase, iconSize && `${iconBase}--${iconSize}`, isRotating && `${iconBase}--rotate`)} - 禁止在 JS 中直接查
document.querySelector('.icon--rotate')—— 应该通过 data 属性或事件委托控制行为,把类名真正当“视觉输出”,而非逻辑入口
最易被忽略的一点:BEM 的 -- 和 __ 不是装饰,是契约。一旦写成 .icon__rotate,你就承诺这个 rotate 是某个图标内部的子节点;而实际它只是图标自身的一个状态。契约错位,后面所有人读代码都会卡住。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











