unocss 图标方案,这可能是图标的最佳实践

5,916 阅读5分钟

本文首发稀土掘金社区,未经本人允许,不可转载

大家好,我是大脸怪。

图标方案有哪些

在介绍 unocss 图标方案之前,先简单铺垫下常用的图标方案有哪些

1. 雪碧图

雪碧图,又称CSS 精灵,是一种将多个小图标合并到一张大图中的技术。通过将许多小图片放在同一张图片上,然后按照一定的距离隔开,通过设置相应的background-position来显示不同的图标。

使用麻烦,目前已经基本不再使用了

2. Iconfont

字体图标,是一种将图标以字体的形式呈现的技术,优点是放大不会失真,可以通过css样式改变大小和颜色,缺点是不支持多色图标,依赖字体文件无法按需引入。

常用的字体图标库有:

  1. Font Awesome
  2. iconfont-阿里巴巴矢量图标库

3. 纯CSS图标

纯CSS图标就是使用纯css写的图标,比较小众,开销是最小的,但局限性也非常大,只能实现一些比较简单的图标,图标库很少很少,可以参考前端大佬张鑫旭的实现 纯CSS小图标

4. svg

svg本身不是一种图标方案,但它可以作为图标使用,也有很多基于svg实现的图标方案,如上面提到的两个字体图标库也都支持svg,还有 iconify

同时,基于 iconify 的解决方案也有不少,如 unplugin-icons,还有我们今天的主角 Unocss 图标方案

unocss 图标方案

虽然 unocss 图标 是基于 svg 和 iconify 的,但它其实是纯css图标,它的实现原理可以参考 antfu 的文章 聊聊纯 CSS 图标 (antfu.me),里面详细的讲解了 antfu 大佬的的图标探索之旅,一步步的将图标方案打磨成现在的 unocss 图标方案

怎么使用

为了方便演示介绍,我将使用 vite 创建一个全新的项目一步步引导大家如何使用,没有一行多余的代码,零干扰

  1. 使用vite创建一个vue项目,并安装依赖,这里使用的是 pnpm,你也可以使用 npm
pnpm create vite unocss-icon
# 选择 Vue -> JavaScript

cd ./unocss-icon
pnpm i
  1. 安装依赖 unocss@iconify/json
pnpm i unocss @iconify/json
  1. 修改vite配置文件 vite.config.js,添加 unocss plugin
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import Unocss from 'unocss/vite'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    vue(),
    Unocss()
  ],
})
  1. 在项目根目录下创建unocss的配置文件 uno.config.js,并配置如下
import { defineConfig, presetIcons, presetUno } from 'unocss'

export default defineConfig({
  presets: [
    presetUno(),
    presetIcons({
      warn: true,
      prefix: ['i-'],
      extraProperties: {
        display: 'inline-block',
      },
    })
  ]
})
  1. 在入口文件 src/main 引入 uno.css,顺便去掉 style.css 引入
import { createApp } from 'vue'
import 'uno.css'
import App from './App.vue'

createApp(App).mount('#app')
  1. 清空 App.vue 内容,修改成以下
<template>
  <div class="flex gap-3 text-5xl text-red-300">
    <i class="i-vscode-icons:file-type-light-pnpm" />
    <i class="i-vscode-icons:file-type-light-pnpm?mask" />
  </div>
</template>
  1. 启动项目验证一下生不生效, 看到以下页面就表示生效了

image.png

这里我们演示了unocss支持的两种模式的图标,多色图标和背景图标,一般情况下我们使用背景图标居多,背景图标的颜色会跟随上下文的颜色,也可以添加样式修改它的颜色,多色图标则不能调整颜色,它更像是一个 Emoji,同时两种模式的图标都支持修改尺寸,只需要修改font-size 就行了

怎么找图标?

iconify 生态的图标都可以使用,具体可以在这里查找 Icônes (icones.js.org),ps: 这也是 antfu 大佬写的,太强了~

image.png

怎么用图标?

首先根据关键字查找你需要图标

image.png

然后选中图标,点击以下图示的复制,将复制的内容加到标签的class中即可

image.png

具体规则:<i class="i-[图标集名称]:[图标名称]" />

注意:i标签不是固定的,也可以使用 div 或者其他标签。i- 是固定前缀,可以在 uno.config.js 中进行配置

总结

unocss 图标的优点

  1. 完美兼容 iconify 生态,一百多个图标集,二十多万个图标可直接使用,同时还可以使用自定义图标(后面会单独写一篇文章介绍)
  2. 缩放不失真
  3. 字体颜色和大小跟随上下文
  4. 支持多色图标,类似 Emoji
  5. 跟unocss集成使用,配置简单,一个图标就是一个css类
  6. 方便更新图标,有新的图标直接更新 @iconify/json 依赖包就行
  7. 按需使用,虽然图标的选择很多很多,但其实用到多少就加载多少,没有心理负担

unocss 图标方案的不足

我想了想,unocss 图标方案唯一的不足就是大概就是无法在运行时环境动态加载图标吧,当然,这也基本是所有图标方案的不足之处,当然,除了 iconify,不过 iconify 虽然可以动态加载,但它存在别的问题,就是它依赖于网络请求,这使得图标不仅会有闪烁问题,而且在某些内网环境无法请求加载图标。

得益于 unocss 的 safelist 配置,这点不足可以在一定程度上缓解,就是将可能需要动态加载的图标类加到 safelist 中,不过这不是一个完美的方案,它会加大打包后的css的体积,加大多少取决于 safelist 加了多少图标,根据我的测试 342 个图标大概加大了 270k 大小,gzip 后 60k 不到,这点大小我觉得完全没必要在意。

unocss 图标方案的强大不止于此,由于篇幅较长,后面我将单独写一篇文章介绍它的自定义图标集功能,它有很多集成方式,感兴趣的可以在unocss官方文档查阅 图标预设(unocss.dev),或者如果你想早点知道我的最佳实践,可以去啃我的开源项目源码 vue-naive-admin (github.com),有不懂的地方可在下方评论区与我交流探讨~

最后,写文章不易,认真写文章更不易,如果这篇文章对你有帮助,请点赞评论,想第一时间看到我最新文章的也可以点个关注,谢谢各位看官老爷们~