圖標預設
在 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.