内联 svg 是高性能图标系统的唯一可行基底,因其支持 dom 操作、css 主题响应、js 动态控制和可访问性;而 img 等方式因黑盒处理、无 viewbox、硬编码颜色等缺陷必然妥协。

内联 SVG 是高性能图标系统的唯一可行基底,其他方式(img、object、iframe、CSS background)在复用性、主题响应、可访问性或运行时控制上必然妥协。
为什么必须用内联 SVG 而不是 img src="icon.svg"
浏览器把 img 中的 SVG 当作黑盒位图处理:DOM 里只有 <img> 节点,没有 <path></path>、<circle></circle> 等子元素。这意味着:
-
document.querySelector("svg path")返回null -
.icon:hover path { fill: red }完全不生效 - 无法用 JS 动态修改
d属性做路径动画 - 暗色模式下图标变黑/消失,因
fill="#000"内联值锁死颜色 - 服务器未返回
image/svg+xmlMIME 类型时,本地双击 HTML 会直接下载 SVG 文件而非渲染
viewBox 不是可选项,而是缩放数学基础
漏掉 viewBox 是图标模糊、裁剪、Safari/旧 WebView 白屏的头号原因。它定义的是逻辑坐标系,不是“画布大小”。
- 错误写法:
<svg width="48" height="48"><circle cx="24" cy="24" r="12"></circle></svg>→ 图形糊成一团 - 正确写法:
<svg width="48" height="48" viewbox="0 0 24 24"><circle cx="12" cy="12" r="6"></circle></svg> -
viewBox="0 0 24 24"表示所有cx、d值都基于这个 24×24 单位系统 - 响应式推荐:
<svg viewbox="0 0 24 24" style="width: 100%; height: auto;"></svg>,再配合fill="currentColor" - 禁止写
viewBox="0 0 0 0"或含负值,浏览器可能静默忽略整个<svg></svg>
用 currentColor 实现主题色穿透,而不是硬编码 fill
SVG 元素默认不继承文字颜色,fill 和 stroke 初始值都是 black,不是 currentColor。
- 设计工具导出的 SVG 常带
fill="#333",会覆盖外部 CSS,导致.icon path { fill: red }失效 - 正确做法:删掉所有子元素上的
fill、stroke内联属性,统一用fill="currentColor" - CSS 只需控制父级:
.icon { color: #007bff; } .icon path { fill: currentColor; } - 这样切换暗色模式只需改
:root或组件的color,无需动 SVG 结构 - 避免在
<style></style>标签或style=""属性中写颜色,调试时难定位且破坏主题一致性
图标系统真正难点不在嵌入,而在复用与维护边界
高频复用场景下,内联 SVG 的体积膨胀和更新同步才是实际瓶颈。此时必须权衡:
- 小项目(≤10 个图标):直接内联,无请求开销,首次渲染即完成
- 中大型项目:用构建工具生成内联
<symbol></symbol>雪碧图,HTML 中用<use href="#icon-home"></use>引用 —— 既保 DOM 可控,又避免重复代码 - 禁用
<use></use>跨文件引用(如href="icons.svg#home"),因跨域、CORS、IE11 兼容性差,且无法被 CSS 变量或currentColor穿透 - 从 Figma/Sketch 导出前,手动删掉冗余
<defs></defs>、<style></style>、外部渐变引用(如url(#gradient)),这些在内联时极易失效 - 所有图标统一使用相同
viewBox尺寸(如"0 0 24 24"),否则 CSS 缩放时比例错乱
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











