scss中@each生成图标类应使用map存储图标名与unicode键值对,通过@each $name, $unicode in $icon-map遍历,content用"#{$unicode}"包裹,并结合&嵌套控制作用域,避免硬编码、重复类名及字体映射不一致问题。

SCSS中@each生成图标类的基本写法
直接用@each遍历图标名数组,配合#{}插值生成类名是最常用也最稳妥的方式。关键不是“能不能写”,而是变量结构是否清晰、命名是否可维护。
常见错误是把图标名和对应 Unicode 混在一起写死在循环里,导致后期增删图标时要改两处——既改数组又改映射逻辑。
- 推荐把图标名和 Unicode 分离:用
map存储键值对,比如$icon-map: ("home": "\e900", "user": "\e901") - 循环必须用
@each $name, $unicode in $icon-map,不能只写@each $item in $icon-map(会报错,map不能直接遍历) -
content属性值必须加引号包裹"#{$unicode}",否则编译后变成未定义变量或字面量错误
避免CSS选择器重复和 specificity 冲突
批量生成的图标类默认都是单类名(如.icon-home),但实际项目中常需要限定作用域,比如只在.header下生效,或避免和第三方UI库冲突。
不加控制地全局输出.icon-*容易被更高优先级规则覆盖,尤其当项目用了!important或嵌套过深的选择器时。
- 用
&嵌套控制作用域:.icon { @each $name, $unicode in $icon-map { &-#{$name} { ... } } },生成.icon-home而非.icon-home裸类 - 若需支持前缀开关,可加
$icon-prefix: "ic"变量,类名拼成.#{$icon-prefix}-#{$name} - 别在循环里写
display: inline-block等通用样式——应单独抽离基础类,循环只负责content和font-family
Unicode与字体加载时机不一致导致图标空白
生成的::before内容显示为空白,不是SCSS写错了,大概率是字体文件没加载完、font-family没匹配上,或者 Unicode 值本身不对。
SCSS只是静态生成代码,它不校验字体是否真包含该字符。很多团队用 Fontello 或 IcoMoon 导出字体后,忘了更新$icon-map里的 Unicode 值,旧值还在用。
- 每次更新图标字体后,必须重新导出
_icons.scss或手动核对$icon-map中的 Unicode 值 - 确保
font-family声明在::before规则中显式写出,不要依赖继承;例如font-family: "icon-font", sans-serif - 开发时打开浏览器开发者工具 → Elements → 选中元素 → Computed → 查看
content是否正确解析为字符,再看font-family是否命中目标字体
要不要用@for或@while替代@each?
不用。除非你在生成带数字后缀的类(如.col-1到.col-12),否则@for和@while在这里纯属增加复杂度。
图标名是语义化字符串,不是连续整数,强行用索引去取会导致可读性归零,且无法做键值映射——你没法靠$i知道第3个图标到底是"search"还是"close"。
-
@each天然适配键值对,语义明确,调试友好 -
@for $i from 1 through length($list)需要额外调用nth($list, $i),多一层间接,还容易越界 - 如果真有动态生成需求(比如从JSON注入图标数据),那该换构建工具链(如用PostCSS或自定义Webpack loader),而不是在SCSS里硬扛
真正难的从来不是写几行@each,而是让图标数据源、字体文件、SCSS变量三者长期对得上。每次图标增减,都要同步三处——这里最容易漏掉的是字体文件里的 Unicode 映射表更新。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











