Skip to content

图标预设

通过 UnoCSS 使用纯 CSS 样式来显示任意图标

源代码

TIP

推荐阅读: 聊聊纯 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="i-mdi-alarm text-orange-400" />
<!-- A large Vue logo -->
<div class="i-logos-vue text-3xl" />
<!-- 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]

我们使用 Iconify 作为图标的数据源。您需要按照 @iconify-json/* 模式在 devDependencies 中安装相应的图标集。例如, @iconify-json/mdi 表示Material Design Icons@iconify-json/tabler 表示 Tabler。您可以参考 IcônesIconify 了解所有可用的集合。

ts
// uno.config.ts
import { defineConfig } from 'unocss'
import presetIcons from '@unocss/preset-icons'

export default defineConfig({
  presets: [
    presetIcons({ /* options */ }),
    // ...other presets
  ],
})

TIP

此预设包含在 unocss 包中,您也可以从那里导入它:

ts
import { presetIcons } from 'unocss'

INFO

您还可以单独使用此预设作为现有 UI 框架的补充,以获得纯 CSS 图标!

如果您希望一次安装 Iconify 上可用的所有图标集 (~130MB):

bash
pnpm add -D @iconify/json
bash
yarn add -D @iconify/json
bash
npm install -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="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/[the-collection-you-want]@iconify/json 提供集合,或者使用 UnoCSS 配置上的 collections 选项使用自定义集合。

浏览器

要加载 iconify 集合,您应该使用 @iconify-json/[the-collection-you-want] 而不是 @iconify/json ,因为 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](https: //github.com/iconify/iconify/blob/master/packages/utils/src/loader/types.ts#L86),例如使用 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](https 😕/github.com/iconify/iconify/blob/master/packages/utils/src/loader/types.ts#L100)。

FileSystemIconLoader

此外,您还可以使用 FileSystemIconLoader 从文件中加载自定义图标系统。您需要将 @iconify/utils 包安装为 dev dependency

ts
// uno.config.ts
import fs from 'node:fs/promises'
import { defineConfig, presetIcons } from 'unocss'

// loader helpers
import { FileSystemIconLoader } from '@iconify/utils/lib/loader/node-loaders'

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 工具类,来加载其他作者的图标库

WARNING

外部包必须包含 icons.json 文件,其中包含 IconifyJSON 格式的 icons 数据,该文件可以使用 Iconify Tools 导出。查看 将图标集导出为 JSON 包 了解更多详细信息。

例如,您可以使用 an-awesome-collection@my-awesome-collections/some-collection 来加载自定义或第三方图标:

ts
// 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')
    })
  ]
})

您还可以将其与其他自定义图标加载器结合使用,例如:

ts
// 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: 更改默认图标自定义值。

对于每个加载的图标,自定义功能执行顺序如下:

  • 如果提供了自定义图标集,对原始 svg 将先执行 transform
  • 如果定义了 customize ,将执行
  • 如果对 customize定义了 iconCustomizer ,将执行

全局自定义图标转换

加载自定义图标时,您可以对其进行转换,例如使用 currentColor 替换当前颜色

ts
presetIcons({
  customizations: {
    transform(svg) {
      return svg.replace(/#fff/, 'currentColor')
    }
  }
})

从版本 0.30.8 开始,transform 提供了 collectionicon 名称:

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 将应用于任何图标集,即对来源于 自定义 加载器、行内 自定义图标集 或者 @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'
      }
    }
  }
})

选项

scale

  • Type: number
  • Default: 1

与当前字体大小相关的比例 (1em)。

mode

生成 CSS 图标的模式。

TIP

  • mask - 使用 CSS 的 background-color 属性和 mask 属性来生成单色图标
  • background-img - 使用 CSS 的 background-image 属性来生成图标,颜色是静态的
  • auto - 根据每个图标的样式智能决定使用 mask 或者 background-img

prefix

  • Type: string | string[]
  • Default: 'i-'

用于匹配图标规则的类前缀。

extraProperties

  • Type: Record<string, string>
  • Default: {}

用于生成额外的 CSS 属性。

warn

  • Type: boolean
  • Default: false

当匹配不到图标时发出警告。

collections

  • Type: Record<string, (() => Awaitable<IconifyJSON>) | undefined | CustomIconLoader | InlineCollection>
  • Default: undefined

在 Node.js 环境中,预设会自动搜索已安装的 iconify 数据集。在浏览器中使用时,提供此选项是为了向数据集提供自定义加载机制。

layer

  • Type: string
  • Default: 'icons'

规则层。

customizations

  • Type: Omit<IconCustomizations, 'additionalProps' | 'trimCustomSvg'>
  • Default: undefined

自定义图标的 customizations.

autoInstall

  • Type: boolean
  • Default: false

Auto install icon sources package when the usages is detected. 检测到图标被使用时,自动安装资源包。

WARNING

仅在 node 环境中有效,在 browser 上此选项将被忽略。

unit

  • Type: string
  • Default: 'em'

自定义图标单位。

cdn

  • Type: string
  • Default: undefined

从 CDN 加载图标。应以 https:// 开头并以 /结尾。

推荐:

  • https://esm.sh/
  • https://cdn.skypack.dev/

customFetch

  • Type: (url: string) => Promise<any>
  • Default: undefined

预设使用 ofetch 作为默认的 fetcher,您也可以自定义 fetch 函数来提供图标数据。

processor

  • Type: (cssObject: CSSObject, meta: Required<IconMeta>) => void
  • Default: undefined
ts
interface IconMeta {
  collection: string
  icon: string
  svg: string
  mode?: IconsOptions['mode']
}

stringify 之前 CSS 对象的处理器。请参阅 示例

自定义图标集清理进阶

将此预设与自定义图标一起使用时,请使用类似于 Iconify 对任何图标集执行的清理过程。您需要的所有工具都可以在 Iconify 工具 中找到。

您可以参考示例:[@iconify/tools/@iconify-demo/unocss](https://github.com/iconify/tools/tree/main/%40iconify-演示/unocss),在 Vue 3 项目里使用此预设。

Iconify ,阅读 Cleaning up icons 了解更多详细信息。

Credits

基于 MIT 许可发布