图标方案
iconctl 写出的是 Iconify JSON(以及可选的 SVG 文件)。那是工程源。各端怎么把图标画出来,是另一件事。i-brand-arrow-left 是 CSS class,通常是 mask,不是字体。
目录
这页出现过的绘制方案都在这里。主流指 2020 年代新做的 Web / 小程序 UI 实际在发什么,不是 iconfont.cn 还在生成什么。
| 方案 | 现状 | 干什么 |
|---|---|---|
| CSS mask | 主流 | 产品 UI + 小程序。iconctl 默认。 |
| 内联 SVG | 主流 | Vue/React 组件、动画、无障碍。 |
| Iconify 运行时 | 主流 | 公共图标集 / 已经有 @iconify/vue 的应用。 |
| SVG 文件 | 按需 | 插画、Logo、<img>。 |
| CSS background | 按需 | 多色图标还想用 class。 |
| Symbol 雪碧图 | 遗留 | <use> / iconfont Symbol JS。国内还常见。 |
| Webfont | 遗留 | @font-face + 私用区。国内还常见。 |
iconctl 不会产出 webfont 或 symbol JS。iconfont Symbol URL 是输入。PNG、原生 iOS/Android 矢量这里不展开。
CSS mask
主流。 mask-image 加上 background-color: currentColor。class 写法和 iconfont 一样(i-brand-arrow-left),没有字体基线问题,UnoCSS 或 @iconify/tailwind4 能按用到的 class 裁 CSS。只能单色。这是小程序的做法,也是 iconctl 在 Web 上的默认。
跟着取色器
<span class="i-demo-arrow-left"></span>内联 SVG
组件应用里的主流。把 <svg> 写进 HTML 或 Vue/React SFC,画法一样。CSS、动画、aria / title 都好做。同一图标在页面里复制很多次,标记会胀。小程序不能像浏览器那样吃 SVG。演示 画廊把 JSON body 内联进去是预览,不是生产 class API。
跟着取色器
<svg viewBox="0 0 24 24" aria-hidden="true">…</svg>Iconify 运行时
公共图标集、以及已经跑着 @iconify/vue(或 web component)的应用,这是主流。JSON 进,内联 SVG 出。多一段 JS。小程序不能用。iconctl 在 Web 上默认仍是构建期出 CSS。
跟着取色器
<Icon icon="demo:arrow-left" />SVG 文件
按需。 <img src="arrow-left.svg">。缓存简单。颜色写死,不会跟 text-primary。小程序的 <image> 经常不认 SVG。插画和 Logo 用这个,24px 的 UI 套件别用。
颜色写死,不跟取色器
<img src="arrow-left.svg" alt="" width="24" height="24">CSS background
按需。 background-image 放 data-URI 或文件,不用 mask。多色能保住,currentColor 没有。图标本身就是多色、又还想用 class 时用这个。
颜色写死,不跟取色器
.icon { background: url("arrow-left.svg") center / contain no-repeat; }Symbol 雪碧图
遗留,国内 iconfont 流程里还常见。一份文件里一堆 <symbol id>,再用 <svg><use href="#id"></use></svg>。iconfont 的 Symbol 就是这个,外加一段注入 JS。宿主 SVG 上可以 currentColor。外链 sprite 会碰到 CORS;不按应用重生就会整包下载。微信 / 支付宝 / 抖音基本没有 <use>。iconctl 不写这种产物。
跟着取色器
<svg><use href="#arrow-left" /></svg>Webfont
遗留,iconfont.cn 还在发。@font-face 加私用区字形。HTML 短,大家熟。整份字体都要下,FOUT,基线会漂,私用区不是真文字。下面的字形是演示字体(描边被收成填充),不是 iconctl 产物。不要从这套管线再出 webfont。如果已经有 Symbol CDN,当源收进来,然后丢掉字体。
跟着取色器
<i class="icon-arrow-left"></i>多维打分(1–5)
没有总分。webfont 的 HTML 很短,加总会把它抬上去;那不是这套管线要的。最后一行是和 iconctl 应用的契合,不是宇宙排名。
| CSS mask | 内联 SVG | Iconify 运行时 | SVG 文件 | CSS background | Symbol | Webfont | |
|---|---|---|---|---|---|---|---|
| 跟随主题色 | 5 | 5 | 5 | 1 | 1 | 5 | 5 |
| 多色 | 1 | 5 | 5 | 5 | 5 | 2 | 1 |
| 按需裁剪 | 5 | 4 | 4 | 4 | 5 | 2 | 1 |
| 请求与缓存 | 5 | 5 | 3 | 2 | 4 | 3 | 2 |
| 对齐 | 5 | 5 | 5 | 5 | 5 | 4 | 2 |
| 无障碍 | 3 | 5 | 5 | 3 | 3 | 3 | 1 |
| 小程序 | 5 | 1 | 1 | 2 | 3 | 1 | 2 |
| 动画 | 2 | 5 | 5 | 1 | 1 | 3 | 2 |
| class 写法 | 5 | 2 | 4 | 2 | 5 | 3 | 5 |
| 和 iconctl 的契合 | 5 | 3 | 3 | 2 | 2 | 2 | 1 |
什么场景用什么
| 场景 | 用 | 别用 |
|---|---|---|
| Vite + UnoCSS / Tailwind | CSS mask,class i-{prefix}-{name} | 新做 webfont |
| 微信 / 支付宝 / 抖音 | 同一套 class,CSS mask | <use>、webfont、Iconify Vue |
| 图标少,要动画或多色 SVG | 内联 SVG 或 Iconify 运行时 | mask(单色)、webfont |
| 多色 Logo / 插画 | <img>、CSS background,或位图 | Iconify / mask |
| 已经在用 @iconify/vue 的公共图标集 | Iconify 运行时 | 再走一遍 iconctl |
| 现成的 iconfont Symbol CDN | { type: 'iconfont' } 收进来,再用 mask 画 | 继续发字体 |
| 给设计和 QA 预览 | 内联 SVG 画廊(iconctl preview / Demo) | 把预览当生产 API |
补充:口头那四个名字
常听人说「SVG / webfont / symbol / CSS mask」。这四个把文件格式、传输方式和绘制方式混在一起了:
| 口头说法 | 实际多半指 |
|---|---|
| SVG | 内联 <svg>、<img src="*.svg">,或 CSS background-image |
| Symbol | SVG sprite 的 <symbol> + <use>,或 iconfont.cn 的 Symbol JS |
| CSS mask | mask-image + background-color: currentColor |
| Webfont | @font-face + 私用区字形 |
上面的目录才是这套产品实际在拆的方案。