UnoCSS的preset-icons通过类名直接渲染SVG图标,不依赖字体、无加载延迟、颜色大小由CSS控制;需安装对应JSON图标包(如@iconify-json/mdi),配置presetIcons并传入选项对象,类名格式为i-图标集-图标名(如i-mdi-home),大小写敏感且需匹配Iconify官网名称。

UnoCSS 的 preset-icons 能直接用类名渲染 SVG 图标,不依赖字体文件、无跨域/加载延迟、颜色大小随 CSS 控制——它不是“另一种图标字体”,而是把 SVG 当作一等公民塞进原子化系统里。
安装图标集并启用 preset-icons
UnoCSS 本身不带图标数据,必须显式安装对应图标集的 JSON 包。比如要用 Material Design Icons,就装 @iconify-json/mdi;要用 Carbon,就装 @iconify-json/carbon。注意:只装 JSON 包,不装 JS 渲染器或字体文件。
- 运行
pnpm add -D @iconify-json/mdi(或你选的图标集) - 在
uno.config.ts中引入并配置presetIcons,不能只写presetIcons(),必须传入选项对象,否则图标不会被识别 - 确保
presets数组里同时有presetUno()(或其他基础预设),否则i-xxx类名无法触发解析
类名格式与常见错误
图标类名固定为 i-图标集-图标名,比如 i-mdi-home、i-carbon-sun。大小写敏感,且图标名必须和 Iconify 官网查到的完全一致(如 mdi:home → i-mdi-home,中间是短横线,不是冒号)。
- 写成
i-mdi:home或i-MDI-home都不会生效,控制台也无报错,图标直接空白 - 图标名含连字符(如
arrow-left)时,类名就是i-mdi-arrow-left,无需转义或驼峰 - 如果用了
extraProperties配置但没加display: inline-block,图标可能塌陷成一条线——这是最常被忽略的显示问题
按需打包与 Tree-shaking 生效条件
UnoCSS 默认只生成你实际在模板中写的 i-xxx 类对应的 SVG Data URI,但这个行为不是自动的,依赖两个硬性条件:
立即学习“前端免费学习笔记(深入)”;
-
include配置必须覆盖你写类名的文件(如/\.vue$/、/\.tsx?$/),否则扫描不到类名,所有图标都会被丢弃 -
exclude必须排除node_modules,否则构建会卡住或体积暴增——尤其当你项目里有其他依赖也用了 iconify 时 - 动态拼接类名(如
:class="`i-${iconName}`")无法被静态分析,这类图标不会进入打包,得手动在extend或icons选项里声明
本地 SVG 图标如何接入
UnoCSS 支持直接引用本地 .svg 文件,但路径必须是相对于项目根目录的绝对路径(以 / 开头),且文件需在构建时可访问(不能放在 public/ 下,得放 src/assets/icons/ 这类会被打包处理的目录)。
- 写法是
i-[~icons/heart],其中[~icons/heart]是路径别名,需在uno.config.ts的theme.paths或 Vite 的resolve.alias中提前定义 - 本地 SVG 不支持自动 color / size 变换,因为它是作为 background-image 插入的,只能靠
background-size和color(对 fill 属性无效)间接控制 - 如果 SVG 内联了
fill="currentColor",那配合color类(如c-red)就能变色;否则得用filter: invert()等 hack 方式
真正关键的不是“能不能用”,而是理解 UnoCSS 图标本质是编译期注入的 Data URI —— 它没有运行时开销,但也意味着一切都要在构建前确定;动态图标、主题切换、SSR 下的首次渲染一致性,都得围绕这个前提设计。


















