图标预设
在 UnoCSS 中使用纯 CSS 的任何图标。
TIP
推荐阅读:纯 CSS 中的图标
遵循以下约定使用图标
<前缀><集合>-<图标>
<前缀><集合>:<图标>
例如:
<!-- 来自 Phosphor 图标的基本锚点图标 -->
<div class="i-ph-anchor-simple-thin" />
<!-- 来自 Material Design Icons 的橙色警报 -->
<div class="i-mdi-alarm text-orange-400" />
<!-- 大型 Vue 徽标 -->
<div class="i-logos-vue text-3xl" />
<!-- 亮模式下的太阳,暗模式下的月亮,来自 Carbon -->
<button class="i-carbon-sun dark:i-carbon-moon" />
<!-- 笑脸表情,悬停时变为流泪表情 -->
<div class="i-twemoji-grinning-face-with-smiling-eyes hover:i-twemoji-face-with-tears-of-joy" />
查看所有可用图标。
安装
pnpm add -D @unocss/preset-icons @iconify-json/[你想要的集合]
yarn add -D @unocss/preset-icons @iconify-json/[你想要的集合]
npm install -D @unocss/preset-icons @iconify-json/[你想要的集合]
我们使用 Iconify 作为图标的数据源。你需要按照 @iconify-json/*
模式在 devDependencies
中安装相应的图标集。例如,@iconify-json/mdi
用于 Material Design Icons,@iconify-json/tabler
用于 Tabler。你可以参考 Icônes 或 Iconify 查看所有可用的集合。
// uno.config.ts
import { defineConfig } from 'unocss'
import presetIcons from '@unocss/preset-icons'
export default defineConfig({
presets: [
presetIcons({ /* 选项 */ }),
// ...其他预设
],
})
TIP
这个预设已包含在 unocss
包中,你也可以从那里导入:
import { presetIcons } from 'unocss'
INFO
你还可以单独使用这个预设作为现有 UI 框架的补充,以获得纯 CSS 图标!
如果你希望一次性安装 Iconify 上所有可用的图标集(约 130MB):
pnpm add -D @iconify/json
yarn add -D @iconify/json
npm install -D @iconify/json
额外属性
你可以提供额外的 CSS 属性来控制图标的默认行为。以下是使图标默认内联的示例:
presetIcons({
extraProperties: {
'display': 'inline-block',
'vertical-align': 'middle',
// ...
},
})
模式覆盖
默认情况下,此预设将根据每个图标的特征自动选择渲染模式。你可以在这篇博客文章中了解更多。在某些情况下,你可能希望为每个图标显式设置渲染模式。
?bg
用于background-img
- 将图标渲染为背景图像?mask
用于mask
- 将图标渲染为蒙版图像
例如,vscode-icons:file-type-light-pnpm
,一个带有颜色的图标(svg
不包含 currentColor
),将被渲染为背景图像。使用 vscode-icons:file-type-light-pnpm?mask
将其渲染为蒙版图像并绕过其颜色。
<div class="w-full flex items-center justify-center gap-x-4 text-4xl p-2 mt-4">
<div class="i-vscode-icons:file-type-light-pnpm" />
<div class="i-vscode-icons:file-type-light-pnpm?mask text-red-300" />
</div>
配置集合和图标解析器
你可以通过 @iconify-json/[你想要的集合]
、@iconify/json
或使用 UnoCSS
配置中的 collections
选项来提供自定义集合。
浏览器
要加载 iconify
集合,你应该使用 @iconify-json/[你想要的集合]
而不是 @iconify/json
,因为 json
文件很大。
打包工具
使用打包工具时,你可以使用 动态导入
提供集合,这样它们将作为异步块打包并按需加载。
import presetIcons from '@unocss/preset-icons/browser'
export default defineConfig({
presets: [
presetIcons({
collections: {
carbon: () => import('@iconify-json/carbon/icons.json').then(i => i.default),
mdi: () => import('@iconify-json/mdi/icons.json').then(i => i.default),
logos: () => import('@iconify-json/logos/icons.json').then(i => i.default),
}
})
]
})
CDN
如果你更喜欢从 CDN 获取,可以自 v0.32.10
起指定 cdn
选项。我们推荐 esm.sh 作为 CDN 提供商。
presetIcons({
cdn: 'https://esm.sh/'
})
自定义
你还可以使用 CustomIconLoader 或 InlineCollection 提供自己的自定义集合,例如使用 InlineCollection
:
presetIcons({
collections: {
custom: {
circle: '<svg viewBox="0 0 120 120"><circle cx="60" cy="60" r="50"></circle></svg>',
/* ... */
},
carbon: () => import('@iconify-json/carbon/icons.json').then(i => i.default as any),
/* ... */
}
})
然后,你可以在 HTML 中使用:<span class="i-custom:circle"></span>
Node.js
在 Node.js
中,预设将自动搜索已安装的 Iconify 数据集,因此你不需要注册 iconify
集合。
你还可以使用 CustomIconLoader 或 InlineCollection 提供自己的自定义集合。
文件系统图标加载器
此外,你还可以使用 FileSystemIconLoader 从文件系统加载自定义图标。你需要安装 @iconify/utils
作为开发依赖。
// uno.config.ts
import fs from 'node:fs/promises'
import { defineConfig, presetIcons } from 'unocss'
// 加载器帮助程序
import { FileSystemIconLoader } from '@iconify/utils/lib/loader/node-loaders'
export default defineConfig({
presets: [
presetIcons({
collections: {
// 集合名称作为键
'my-icons': {
account: '<svg><!-- ... --></svg>',
// 懒加载自定义图标
settings: () => fs.readFile('./path/to/my-icon.svg', 'utf-8'),
/* ... */
},
'my-other-icons': async (iconName) => {
// 你的自定义加载器。想怎么做就怎么做。
// 例如,从远程服务器获取:
return await fetch(`https://example.com/icons/${iconName}.svg`).then(res => res.text())
},
// 帮助从文件系统加载图标
// 将在 `./assets/icons` 下以 `.svg` 扩展名加载的文件作为其文件名
// 你还可以提供一个转换回调来更改每个图标(可选)
'my-yet-other-icons': FileSystemIconLoader(
'./assets/icons',
svg => svg.replace(/#fff/, 'currentColor')
)
}
})
]
})
外部包图标加载器
从 @iconify/utils v2.1.20
开始,你可以使用 createExternalPackageIconLoader 帮助程序从其他作者的包中加载图标。
警告
外部包必须包含 icons.json
文件,其中包含 IconifyJSON
格式的 icons
数据,可以使用 Iconify 工具导出。请查看 将图标集导出为 JSON 包 了解更多详情。
例如,你可以使用 an-awesome-collection
或 @my-awesome-collections/some-collection
来加载自定义或第三方图标:
// uno.config.ts
import { defineConfig, presetIcons } from 'unocss'
import { createExternalPackageIconLoader } from '@iconify/utils/lib/loader/external-pkg'
export default defineConfig({
presets: [
presetIcons({
collections: createExternalPackageIconLoader('an-awesome-collection')
})
]
})
你还可以将其与其他自定义图标加载器结合使用,例如:
// uno.config.ts
import { defineConfig, presetIcons } from 'unocss'
import { FileSystemIconLoader } from 'unplugin-icons/loaders'
import { createExternalPackageIconLoader } from '@iconify/utils/lib/loader/external-pkg'
export default defineConfig({
presets: [
presetIcons({
collections: {
...createExternalPackageIconLoader('other-awesome-collection'),
...createExternalPackageIconLoader('@my-awesome-collections/some-collection'),
...createExternalPackageIconLoader('@my-awesome-collections/some-other-collection'),
'my-yet-other-icons': FileSystemIconLoader(
'./assets/icons',
svg => svg.replace(/^<svg /, '<svg fill="currentColor" ')
)
}
})
]
})
图标自定义
你可以使用 customizations
配置选项自定义所有图标。
可用的自定义函数:
transform
:转换原始svg
,仅在使用custom
图标集合时应用(不包括iconify
集合)。customize
:更改默认图标自定义值。iconCustomizer
:更改默认图标自定义值。
对于每个加载的图标,自定义将按以下顺序应用:
- 如果提供并使用自定义图标集合,则应用
transform
到原始svg
- 应用带有默认自定义的
customize
(如果提供) - 应用带有
customize
自定义的iconCustomizer
(如果提供)
全局自定义图标转换
加载自定义图标时,你可以转换它们,例如添加 fill
属性为 currentColor
:
presetIcons({
customizations: {
transform(svg) {
return svg.replace(/#fff/, 'currentColor')
}
}
})
从 0.30.8
版本开始,transform
提供 collection
和 icon
名称:
presetIcons({
customizations: {
transform(svg, collection, icon) {
// 不要为此集合中的此图标应用填充
if (collection === 'custom' && icon === 'my-icon')
return svg
return svg.replace(/#fff/, 'currentColor')
}
}
})
全局图标自定义
加载任何图标时,你可以自定义所有图标的公共属性,例如配置相同的大小:
presetIcons({
customizations: {
customize(props) {
props.width = '2em'
props.height = '2em'
return props
}
}
})
图标/集合自定义
你可以使用 iconCustomizer
配置选项自定义每个图标。
iconCustomizer
将优先于配置。
iconCustomizer
将应用于任何集合,即来自 custom
加载器、custom collections
上的 inlined
或来自 @iconify
的图标。
例如,你可以配置 iconCustomizer
更改集合中的所有图标或集合中的单个图标:
presetIcons({
customizations: {
iconCustomizer(collection, icon, props) {
// 自定义此集合中的所有图标
if (collection === 'my-other-icons') {
props.width = '4em'
props.height = '4em'
}
// 自定义此集合中的此图标
if (collection === 'my-icons' && icon === 'account') {
props.width = '6em'
props.height = '6em'
}
// 自定义此 @iconify 集合中的此图标
if (collection === 'mdi' && icon === 'account') {
props.width = '2em'
props.height = '2em'
}
}
}
})
选项
scale
- 类型:
number
- 默认值:
1
相对于当前字体大小(1em)的缩放。
mode
- 类型:
'mask' | 'background-img' | 'auto'
- 默认值:
'auto'
- 参见:https://antfu.me/posts/icons-in-pure-css
生成的 CSS 图标的模式。
提示
mask
- 使用背景颜色和mask
属性的单色图标background-img
- 使用背景图像的图标,颜色是静态的auto
- 根据图标样式智能地在mask
和background-img
之间决定模式
prefix
- 类型:
string | string[]
- 默认值:
'i-'
匹配图标规则的类前缀。
extraProperties
- 类型:
Record<string, string>
- 默认值:
{}
应用于生成的 CSS 的额外 CSS 属性。
warn
- 类型:
boolean
- 默认值:
false
当匹配到缺失的图标时发出警告。
collections
- 类型:
Record<string, (() => Awaitable<IconifyJSON>) | undefined | CustomIconLoader | InlineCollection>
- 默认值:
undefined
在 Node.js 环境中,预设将自动搜索已安装的 Iconify 数据集。在浏览器中使用时,此选项用于提供带有自定义加载机制的数据集。
layer
- 类型:
string
- 默认值:
'icons'
规则层。
customizations
- 类型:
Omit<IconCustomizations, 'additionalProps' | 'trimCustomSvg'>
- 默认值:
undefined
自定义图标自定义。
autoInstall
- 类型:
boolean
- 默认值:
false
检测到使用时自动安装图标源包。
警告
仅在 node
环境中有效,在 browser
中此选项将被忽略。
unit
- 类型:
string
- 默认值:
'em'
自定义图标单位。
cdn
- 类型:
string
- 默认值:
undefined
从 CDN 加载图标。应以 https://
开头并以 /
结尾。
推荐:
https://esm.sh/
Advanced Custom Icon Set Cleanup
When using this preset with your custom icons, consider using a cleanup process similar to that done by Iconify for any icons sets. All the tools you need are available in Iconify Tools.
You can check this repo, using this preset on a Vue 3
project: @iconify/tools/@iconify-demo/unocss.
Read Cleaning up icons article from Iconify for more details.
Credits
- This preset is inspired from this issue created by @husayt.
- Based on the work of this PR by @userquin.