Appearance
图标预设
为 UnoCSS 使用纯 CSS 来使用任何图标。
提示
推荐阅读:纯 CSS 中的图标
使用图标请遵循以下约定
<prefix><collection>-<icon>
<prefix><collection>:<icon>
例如:
html
<!-- A basic anchor icon from Phosphor icons -->
<div class="i-ph-anchor-simple-thin" />
<!-- An orange alarm from Material Design Icons -->
<div class="text-orange-400 i-mdi-alarm" />
<!-- A large Vue logo -->
<div class="text-3xl i-logos-vue" />
<!-- Sun in light mode, Moon in dark mode, from Carbon -->
<button class="i-carbon-sun dark:i-carbon-moon" />
<!-- Twemoji of laugh, turns to tear on hovering -->
<div class="i-twemoji-grinning-face-with-smiling-eyes hover:i-twemoji-face-with-tears-of-joy" />
Hover it
查看 所有可用图标。
安装
bash
pnpm add -D @unocss/preset-icons @iconify-json/[the-collection-you-want]
bash
yarn add -D @unocss/preset-icons @iconify-json/[the-collection-you-want]
bash
npm install -D @unocss/preset-icons @iconify-json/[the-collection-you-want]
bash
bun add -D @unocss/preset-icons @iconify-json/[the-collection-you-want]
我们使用 Iconify 作为图标数据源。你需要按照 @iconify-json/*
模式将相应的图标集安装到 devDependencies
中。例如,Material Design Icons 对应的是 @iconify-json/mdi
,Tabler 对应的是 @iconify-json/tabler
。你可以参考 Icônes 或 Iconify 来查看所有可用的图标集。
ts
import presetIcons from '@unocss/preset-icons'
import { defineConfig } from 'unocss'
export default defineConfig({
presets: [
presetIcons({ /* options */ }),
// ...other presets
],
})
提示
此预设包含在 unocss
包中,你也可以从该包中导入它:
ts
import { presetIcons } from 'unocss'
信息
你也可以单独使用这个预设,作为现有 UI 框架的补充,以使用纯 CSS 图标!
如果你倾向于一次性安装 Iconify 上所有可用的图标集(约 130MB):
bash
pnpm add -D @iconify/json
bash
yarn add -D @iconify/json
bash
npm install -D @iconify/json
bash
bun add -D @iconify/json
额外属性
你可以提供额外的 CSS 属性来控制图标的默认行为。以下是一个让图标默认内联显示的示例:
ts
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
可将其渲染为遮罩图像并忽略其颜色。
html
<div class="flex gap-x-4 justify-center items-center p-2 mt-4 w-full text-4xl">
<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
选项提供自定义的图标集合。
浏览器环境
由于 json
文件体积很大,因此在加载 iconify
图标集合时,你应该使用 @iconify-json/[你想要的图标集合]
,而不是 @iconify/json
。
打包工具
在使用打包工具时,你可以使用 动态导入
来提供图标集合,这样它们将被打包为异步块并按需加载。
ts
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 提供商。
ts
presetIcons({
cdn: 'https://esm.sh/'
})
自定义
你还可以使用 CustomIconLoader 或 InlineCollection 来提供你自己的自定义图标集。例如,使用 InlineCollection
:
ts
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
包作为 开发依赖
进行安装。
ts
import fs from 'node:fs/promises'
// loader helpers
import { FileSystemIconLoader } from '@iconify/utils/lib/loader/node-loaders'
import { defineConfig, presetIcons } from 'unocss'
export default defineConfig({
presets: [
presetIcons({
collections: {
// key as the collection name
'my-icons': {
account: '<svg><!-- ... --></svg>',
// load your custom icon lazily
settings: () => fs.readFile('./path/to/my-icon.svg', 'utf-8'),
/* ... */
},
'my-other-icons': async (iconName) => {
// your custom loader here. Do whatever you want.
// for example, fetch from a remote server:
return await fetch(`https://example.com/icons/${iconName}.svg`).then(res => res.text())
},
// a helper to load icons from the file system
// files under `./assets/icons` with `.svg` extension will be loaded as it's file name
// you can also provide a transform callback to change each icon (optional)
'my-yet-other-icons': FileSystemIconLoader(
'./assets/icons',
svg => svg.replace(/#fff/, 'currentColor')
)
}
})
]
})
外部包图标加载器
从 @iconify/utils v2.1.20
版本开始,你可以使用新的 createExternalPackageIconLoader 辅助函数,借助其他包来加载其他作者的图标。
警告
外部包必须包含 icons.json
文件,其中的 icons
数据需采用 IconifyJSON
格式,该格式可使用 Iconify 工具导出。有关更多详细信息,请查看 将图标集导出为 JSON 包。
例如,你可以使用 an-awesome-collection
或 @my-awesome-collections/some-collection
来加载你自定义的或第三方的图标:
ts
import { createExternalPackageIconLoader } from '@iconify/utils/lib/loader/external-pkg'
import { defineConfig, presetIcons } from 'unocss'
export default defineConfig({
presets: [
presetIcons({
collections: createExternalPackageIconLoader('an-awesome-collection')
})
]
})
你也可以将其与其他自定义图标加载器结合使用,例如:
ts
import { createExternalPackageIconLoader } from '@iconify/utils/lib/loader/external-pkg'
import { defineConfig, presetIcons } from 'unocss'
import { FileSystemIconLoader } from 'unplugin-icons/loaders'
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
,则应用默认自定义设置。 - 如果提供了
iconCustomizer
,则应用包含customize
自定义设置的设置。
全局自定义图标转换
在加载自定义图标时,你可以对它们进行转换,例如添加带有 currentColor
的 fill
属性:
ts
presetIcons({
customizations: {
transform(svg) {
return svg.replace(/#fff/, 'currentColor')
}
}
})
从版本 0.30.8
开始,transform
会提供 collection
(图标集)和 icon
(图标)的名称:
ts
presetIcons({
customizations: {
transform(svg, collection, icon) {
// do not apply fill to this icons on this collection
if (collection === 'custom' && icon === 'my-icon')
return svg
return svg.replace(/#fff/, 'currentColor')
}
}
})
全局图标自定义
在加载任何图标时,你都可以自定义它们的通用属性,例如配置相同的尺寸:
ts
presetIcons({
customizations: {
customize(props) {
props.width = '2em'
props.height = '2em'
return props
}
}
})
图标/图标集自定义
你可以使用 iconCustomizer
配置选项自定义每个图标。
iconCustomizer
的优先级高于其他配置。
iconCustomizer
会应用于任何图标集,也就是说,无论是来自 custom
加载器、自定义图标集
内联的图标,还是来自 @iconify
的图标。
例如,你可以配置 iconCustomizer
来更改某个图标集中的所有图标,或者某个图标集中的单个图标:
ts
presetIcons({
customizations: {
iconCustomizer(collection, icon, props) {
// customize all icons in this collection
if (collection === 'my-other-icons') {
props.width = '4em'
props.height = '4em'
}
// customize this icon in this collection
if (collection === 'my-icons' && icon === 'account') {
props.width = '6em'
props.height = '6em'
}
// customize this @iconify icon in this collection
if (collection === 'mdi' && icon === 'account') {
props.width = '2em'
props.height = '2em'
}
}
}
})
指令
你可以在 CSS 中使用 icon()
指令来获取图标的元数据。
css
.icon {
background-image: icon('i-carbon-sun');
}
警告
icon()
依赖于 @unocss/preset-icons
并会使用其配置,请确保你已添加此预设。
有关 icon()
指令的更多信息,请查看 指令。
选项
scale
- 类型:
number
- 默认值:
1
相对于当前字体大小(1em)的缩放比例。
mode
- 类型:
'mask' | 'bg' | 'auto'
- 默认值:
'auto'
- 参考: https://antfu.me/posts/icons-in-pure-css
生成的 CSS 图标的模式。
提示
mask
- 对单色图标使用背景颜色和mask
属性bg
- 对图标使用背景图像,颜色是静态的auto
- 根据每个图标的样式智能地在mask
和bg
模式之间做出选择
prefix
- 类型:
string | string[]
- 默认值:
'i-'
用于匹配图标规则的类前缀。
extraProperties
- 类型:
Record<string, string>
- 默认值:
{}
应用于生成的 CSS 的额外 CSS 属性。
warn
- 类型:
boolean
- 默认值:
false
当匹配到缺失的图标时发出警告。
iconifyCollectionsNames
- 类型:
string[]
- 默认值:
undefined
要使用的额外 @iconify-json
图标集。当存在未在默认图标预设集名称列表中的新 @iconify-json
图标集时,应使用此选项。
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)加载图标。URL 应以 https://
开头,并以 /
结尾。
推荐使用:
https://esm.sh/
https://cdn.skypack.dev/
customFetch
- 类型:
(url: string) => Promise<any>
- 默认值:
undefined
预设使用 ofetch
作为默认的获取器,你也可以自定义获取函数来提供图标数据。
processor
- 类型:
(cssObject: CSSObject, meta: Required<IconMeta>) => void
- 默认值:
undefined
ts
interface IconMeta {
collection: string
icon: string
svg: string
mode?: IconsOptions['mode']
}
在字符串化之前处理 CSS 对象。请参阅 示例。
高级自定义图标集清理
当将此预设与自定义图标一起使用时,请考虑采用类似于 Iconify 对任何图标集所做的清理流程。你所需的所有工具都可以在 Iconify 工具 中找到。
你可以查看这个在 Vue 3
项目中使用此预设的仓库:@iconify/tools/@iconify-demo/unocss。
阅读 Iconify 的 清理图标 文章以了解更多详细信息。
可访问性问题
在使用图标时,考虑到所有潜在用户非常重要。其中一些用户可能正在使用屏幕阅读器,他们需要替代文本才能理解图标的含义。你可以使用 aria-label
属性来提供图标的描述:
html
<a href="/profile" aria-label="Profile" class="i-ph:user-duotone"></a>
如果图标仅用于装饰,不需要文本替代内容,你可以使用 aria-hidden="true"
来向屏幕阅读器隐藏该图标:
html
<a href="/profile">
<span aria-hidden="true" class="i-ph:user-duotone"></span>
My Profile
</a>
还有许多其他为屏幕阅读器提供提示文本的技术,例如,Wind3 预设包含 仅屏幕阅读器可见 类,用于在视觉上隐藏元素,但仍让屏幕阅读器可以访问这些元素。
你可以在网上找到一些关于图标可访问性的优质资源,而且 CSS 图标与图标字体的行为类似,因此你可以使用与图标字体相同的技术。