图标用 SVG 还是 PNG:看这三点
设计与前端发布于 2026-10-31
默认答案是 SVG。但「默认」不等于「永远」,三条判据能覆盖绝大多数场景。
判据一:这个图标需要变颜色吗
要变色的图标必须用 SVG,而且必须内联。
外链的 SVG 有个反直觉的限制:
<!-- 这个图标没法用 CSS 改颜色 -->
<img src="icon.svg">
因为 <img> 里的 SVG 是独立文档,外部 CSS 进不去。想让图标跟随主题色(比如 hover 时变主色),要么内联:
<svg viewBox="0 0 24 24">
<path d="..." fill="currentColor" />
</svg>
要么用 CSS mask:
.icon {
background-color: var(--brand);
mask: url(icon.svg) center / contain no-repeat;
}
第二条路适合「同一个图标要在很多地方用、又都要变色」的场景,缺点是多一层背景色逻辑,透明区域的表现容易出意外。
内联 SVG 的关键是 fill="currentColor" —— 它让图标继承父元素的 color,于是主题切换、hover、禁用态全都自动跟随,不用改图片文件。
这一条是很多「暗色主题下图标看不见」问题的根因:图标是黑色 PNG,暗底上自然消失。
判据二:放大到什么尺寸
SVG 无限缩放不失真;PNG 放大就是插值糊。
一个常见的错误是:为了高清屏导出 4 倍图(比如 96×96 显示成 24×24),于是所有图标都变成大文件。几十个图标加起来,比 SVG 大一个数量级。
| 显示尺寸 | PNG 需要 | SVG |
|---|---|---|
| 16~32px | 1x + 2x 两套 | 一个够 |
| 48~128px | 2 倍图 | 一个够 |
| 打印 / 大幅面 | 不现实 | 唯一选择 |
判据三:内容是「形状」还是「画面」
SVG 擅长几何形状:线条、单色填充、简单渐变。不擅长:
- 照片级写实插画(几万个路径点,文件比 PNG 还大)
- 复杂滤镜、混合模式(浏览器渲染差异大)
- 依赖特定字体的文字(对方没装这个字体就变形,正确做法是转成路径)
所以「插画」和「照片」用位图,「UI 图标」用 SVG,界线大致在这里。
常见失误清单
导出 SVG 时尺寸写死
<svg width="48" height="48" viewBox="0 0 24 24">
width/height 只是默认显示尺寸,缩放在 viewBox 里。但很多设计工具导出时会只留 width/height、不留 viewBox,于是这个 SVG 一旦被放大就糊 —— 因为它已经退化成位图逻辑。
检查方法:打开 SVG 源文件搜 viewBox。没有它就是这个图标不可缩放。
反过来,如果 viewBox 比图形小(比如图形超出 24×24),图标会被裁掉一块,而在设计稿里看不出来 —— 设计软件会把画布外的东西也显示出来。
用 width: 100% 撑满容器
SVG 默认按比例缩放,但父容器如果没有明确尺寸,width:100% 可能让它变得巨大或者塌成 0。给一个显式的 width/height 或 aspect-ratio 更稳。
把图标做成字体
图标字体(iconfont)在 2020 年前后很流行,现在不建议:
- 字符渲染受字体加载影响,会出现空白方块
- 无法做多色
- 屏幕阅读器会把它读成一个字符(需要额外 aria 处理)
- 抗锯齿表现不如 SVG
存量项目可以慢慢替换,新项目别再用。
位图图标用 JPEG
JPEG 不支持透明,图标背景会变成白块或黑块。要位图就用 PNG 或 WebP。
WebP 的位置
WebP 支持透明、体积比 PNG 小 20%~30%,浏览器支持已经很完整。它适合「必须用位图的图标」—— 比如带复杂渐变或阴影的图标。
但 WebP 不适合当 favicon(部分系统不认),也不适合需要被设计软件二次编辑的素材。
批量处理
把一批 PNG 图标转 WebP 或统一尺寸,用图片格式转换;只需要改尺寸和质量的用图片压缩与缩放,支持批量按最长边缩放。
如果图标要加统一底标或型号水印,图片加水印可以批量做。
结论
| 场景 | 选 |
|---|---|
| UI 图标、导航图标、按钮图标 | 内联 SVG + currentColor |
| 需要复用、又要变色 | SVG + CSS mask |
| 复杂插画、截图、照片 | PNG 或 WebP |
| favicon | 见专门那篇 |
| 要导出给非设计人员用的图 | PNG(兼容性最好) |
一句话:能在代码里改的用 SVG,只能是「一张图」的用位图。