内联SVG可实现高质量无损展示并支持交互与样式控制,而img引用SVG会丢失DOM节点、交互和CSS变量适配;必须设置viewBox保证缩放不失真,fill应使用currentColor以支持主题切换,复用图形推荐symbol+use。

svg 标签直接写进 HTML 就能实现高质量无损展示,不需要额外加载、不依赖 CDN、也不用转 base64 —— 但前提是它得“活”在 DOM 里,而不是被当成图片塞进去。
为什么 img 引用 SVG 会丢交互和样式控制
常见错误现象:img src="icon.svg" 在页面上显示正常,但 hover 变色、JS 动态改 fill、暗色模式适配全失效。
-
img加载的是“图像快照”,浏览器只渲染像素结果,内部path、circle等节点根本不在 DOM 中 - 无法用 CSS 选中
svg:hover path,也无法用document.querySelector('svg circle')拿到元素 - 如果 SVG 文件里用了
currentColor或 CSS 变量,img方式下这些都会退化成硬编码值(甚至变黑) - 适合场景:纯静态装饰图、SEO 不敏感的 banner 图、CDN 缓存优先级高的资源
viewBox 是缩放不失真的唯一前提
漏掉 viewBox 是内联 SVG 渲染异常的头号原因,尤其在响应式布局或 Retina 屏下。
- 只设
width="100" height="100"而不设viewBox→ 图形会被拉伸、裁剪或居中溢出 - 正确写法:
<svg width="100%" height="100%" viewBox="0 0 100 100">,其中100 100是逻辑画布尺寸,所有坐标(如cx="50")都基于它 -
viewBox="0 0 0 0"或含负数 → 浏览器静默忽略整个svg,图形消失无报错 - 导出自设计工具的 SVG 常带冗余
width/height,建议删掉,只留viewBox+ CSS 控制占位
内联 SVG 的颜色继承必须显式写 currentColor
默认 fill="black" 和 stroke="none" 是硬编码值,不会随主题切换或父级文字色变化。
- 错误写法:
<path fill="#333" d="...">→ 暗色模式下图标变不可见 - 正确写法:
<path fill="currentColor" d="...">→ 自动继承父级color,支持 :hover、CSS 变量、prefers-color-scheme - 如果需要半透明,用
fill-opacity="0.8",别写fill="rgba(0,0,0,0.8)"(部分旧引擎不支持) - 避免在 SVG 内联
<style>块里写fill,会覆盖外部样式,调试时难定位
复用复杂图形请用 <symbol> + <use>,别复制粘贴
多个相同图标重复写一遍 path,既增大 HTML 体积,又让维护变成噩梦。
- 把共用图形定义在
<svg style="display:none"><symbol id="icon-home">...</symbol></svg>里 - 使用时:
<svg><use href="#icon-home"></svg>(注意是href,不是已废弃的xlink:href) -
<use>实例可单独加 class、设置fill、绑定事件,互不影响 - 如果图标来自第三方导出文件,检查是否含
<defs>或外部引用(如url(#gradient)),内联后这些可能失效
svg,而是当设计稿迭代了五版、图标数量涨到四十个、还要适配深色模式+RTL+动画状态时,你得确保每个 fill 都没写死、每个 viewBox 都没漏、每个 use 都指向正确 ID —— 这些细节一错,问题就藏在看似正常的渲染背后。


















