🔥为什么我坚持用 SVG 做 icon?和 font icon 告别之后太爽了

🔥先说结论:我已经全面弃用 iconfont,只用 SVG

用了 6 年 iconfont,直到一次 icon 闪退 + 一个 retina 模糊问题,我怒转 SVG。现在回看,我只想说:一切都晚了。


🧱背景:IconFont 曾经无处不在

从 2015 年前后起,iconfont 就是前端项目的标配:

  • 上阿里图标库拖几个图,下载 TTF 文件,塞进项目
  • CSS 里 .icon-home:before { content: "\e614"; }
  • 不仅开发快,样式也能自由控制:font-sizecolorline-height 全都随便来

但这个方案,看起来"简单",其实全是坑。


😤踩坑合集:iconfont 到底有哪些问题?

1. 图标"莫名其妙不见了"

是不是经常遇到:

html 复制代码
<i class="iconfont icon-home"></i>

然后某一天上线,页面里这个图标直接不显示。

你 debug 半天,才发现:

  • CDN 的 iconfont.ttf 被阻断了
  • 字体文件升级后,有的 unicode 被重映射
  • 某些浏览器默认阻止远程字体加载

更离谱的:你本地能跑,线上就挂


2. Retina 模糊 + 抗锯齿失败

iconfont 本质是"字体",而不是"图形"。

在 Retina 屏下,你控制再多:

css 复制代码
.icon {
  font-size: 24px;
  -webkit-font-smoothing: antialiased;
}

很多图标的边缘还是毛糙,特别是线性图标,对比度一上来,整个像被压过的 JPG。


3. 无法着色多个颜色

想做个渐变 icon?想让图标局部变色?

抱歉,iconfont 是"字体",不是 SVG,不支持多颜色分区。

你只能:

  • 多套图标叠在一起
  • 加背景图 hack
  • 用 canvas 取色渲染(别笑,这我真干过)

而 SVG 支持:

svg 复制代码
<linearGradient id="grad">
  <stop offset="0%" stop-color="#f00" />
  <stop offset="100%" stop-color="#00f" />
</linearGradient>
<path fill="url(#grad)" d="..." />

效果拉满,iconfont 完全追不上。


4. 组件化极难封装

Vue/React 时代你会写这样的:

jsx 复制代码
<Icon type="home" />

组件里你只能用 switch-case 映射成 <i class="icon-home" />

而 SVG 怎么写?

jsx 复制代码
<svg><use xlinkHref="#icon-home" /></svg>

配合 Vite 插件(如 vite-plugin-svg-icons),你直接:

jsx 复制代码
import Icon from '@/components/Icon'

<Icon name="home" />

无 switch-case,无 class,全自动注册。


🧬SVG 的优势实在太香了

✅ 1. 天然支持响应式 + Retina 适配

SVG 是"矢量图",本质是 XML 描述路径,你怎么放大都不会模糊。

加上 viewBox 一配,任何分辨率都稳。

✅ 2. 可以用 CSS 精准控制每一部分

css 复制代码
.icon path {
  stroke: red;
}

你甚至可以控制动画效果、hover 状态、交互响应。

✅ 3. 能做动画,图标能动起来!

html 复制代码
<path class="animated" d="..." />

再配合 GSAP / CSS Animation,一切都活了。

Font icon?别说动画,它连"变色"都费劲。


💻开发实战:我项目里是这么用的

👉 Step 1: 用工具批量导入 SVG(iconfont 支持导出)

iconfont 阿里 下载 SVG 格式图标:

  • 一键导出所有图标为独立 SVG 文件

👉 Step 2: 用 Vite 插件自动加载

bash 复制代码
pnpm i vite-plugin-svg-icons -D

vite.config.ts:

ts 复制代码
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
import path from 'path'

export default {
  plugins: [
    createSvgIconsPlugin({
      iconDirs: [path.resolve(process.cwd(), 'src/assets/icons')],
      symbolId: 'icon-[name]',
    }),
  ],
}

👉 Step 3: 组件封装 + 使用

封装组件:

tsx 复制代码
const Icon = ({ name, className = '' }) => (
  <svg class={`svg-icon ${className}`} aria-hidden="true">
    <use xlinkHref={`#icon-${name}`} />
  </svg>
)

使用方式:

tsx 复制代码
<Icon name="home" className="text-xl text-blue-500" />

结果图标:

  • 不模糊
  • 支持 tailwind 任意控制尺寸 / 颜色
  • 任意动画加上去也丝滑

🔍性能?其实 SVG 更好

很多人说"SVG 会不会多了 HTTP 请求?",其实:

  • 你可以用 svg-sprite 合并成一个 SVG 文件(类似雪碧图)
  • 你可以 Inline 到 HTML

而 iconfont 的 woff/ttf 文件体积反而大,兼容性也差。


🚫你什么时候不适合 SVG?

  • IE10 以下?别做梦(现在谁还兼容它?)
  • 文件体积有要求 (可能有些svg很大)
  • 对 icon 清晰度没有要求

但总的来说,2025 年了,SVG 基本就是绝对主流方案。


🧠晚用 SVG 三年,悔不当初

我不是说 iconfont 毫无可取之处,但作为前端工程实践而言:

"SVG 是当代 Web icon 的答案,iconfont 是历史的过渡产物。"

所以,别再调字体缩放、别再被 Unicode 问题搞得吐血了。 用 SVG,你会感谢现在的自己。你们怎么看?

📌 你可以继续看我的系列文章

相关推荐
冰暮流星35 分钟前
css之线性渐变
前端·css
徐同保41 分钟前
tailwindcss暗色主题切换
开发语言·前端·javascript
mapbar_front1 小时前
大厂精英为何在中小公司水土不服?
前端
生莫甲鲁浪戴1 小时前
Android Studio新手开发第二十七天
前端·javascript·android studio
细节控菜鸡3 小时前
【2025最新】ArcGIS for JS 实现随着时间变化而变化的热力图
开发语言·javascript·arcgis
2501_916008893 小时前
Web 前端开发常用工具推荐与团队实践分享
android·前端·ios·小程序·uni-app·iphone·webview
SkylerHu4 小时前
前端代码规范:husky+ lint-staged+pre-commit
前端·代码规范
菜鸟una4 小时前
【微信小程序 + 消息订阅 + 授权】 微信小程序实现消息订阅流程介绍,代码示例(仅前端)
前端·vue.js·微信小程序·小程序·typescript·taro·1024程序员节
Yeats_Liao4 小时前
Go Web 编程快速入门 05 - 表单处理:urlencoded 与 multipart
前端·golang·iphone
飞翔的佩奇4 小时前
【完整源码+数据集+部署教程】【运动的&足球】足球场地区域图像分割系统源码&数据集全套:改进yolo11-RFAConv
前端·python·yolo·计算机视觉·数据集·yolo11·足球场地区域图像分割系统