内联SVG是唯一支持变色、暗黑模式、hover动画和文字缩放的方式;需设viewBox、fill="currentColor"、display:block,并清理导出冗余代码。

SVG 图标不是“插进去就行”,关键看你要不要控制颜色、响应暗黑模式、加 hover 动画,或者让图标随文字大小缩放。选错方式,后面改起来反而更费劲。
内联 SVG:要交互、要变色、要适配主题时唯一推荐的方式
把 <svg> 标签直接写进 HTML,是唯一能用 CSS 控制 fill、stroke、绑定 JS 事件、响应 :hover 或 CSS 变量的方案。
- 必须设
viewBox(比如viewBox="0 0 24 24"),否则缩放会变形;只写width/height不够 -
fill和stroke默认不继承父级文字色,得显式写fill="currentColor"才能跟随color变化(暗黑模式、主题切换才真正生效) -
<svg>默认是display: inline,常在底部留白,建议加display: block或vertical-align: middle - 导出自 Sketch/Figma 的 SVG 常含冗余
<defs>、<style>或外部引用(如url(#gradient)),内联后可能失效,需手动清理
<img> 引入 SVG:适合纯静态图标,但别指望改颜色
语法最简单:<img src="/icons/home.svg" alt="首页">,但它本质是“图片”,和 PNG 无异。
- SVG 内部的
<path>完全不可被外部 CSS 选中,svg:hover path { fill: red }无效 - 如果 SVG 文件里写了
fill="#333",那它就永远是 #333,除非你打开文件手动改成fill="currentColor" - 浏览器会缓存,适合复用频繁、内容固定的小图标(如 LOGO、分隔线)
- 本地开发时
img src="xxx.svg"报 404?检查路径是否在public/下,Vite/Webpack 默认只服务该目录
<object> 和 <iframe>:基本不用,有兼容性和隔离问题
虽然规范支持,但实际项目中几乎没优势。
立即学习“前端免费学习笔记(深入)”;
-
<object data="icon.svg" type="image/svg+xml">理论上可 JS 操作内部 DOM,但跨域、CSP、IE 兼容性差,现代框架也难注入样式 -
<iframe src="icon.svg">更糟:完全隔离样式与脚本,SEO 和无障碍访问(screen reader)支持极弱 - 两者都会触发额外 HTTP 请求,且无法用
currentColor继承父级颜色 - 除非你在做微前端或严格隔离第三方 SVG 内容,否则绕开
CSS background-image:仅限装饰性图标,别用在语义化位置
适合按钮背景、卡片角标这类“非关键视觉元素”。
- 写法:
background-image: url(/icons/bell.svg); background-size: contain; - 无法被屏幕阅读器识别,
alt文本完全丢失,不符合 WCAG 基础要求 - 不能响应
em单位缩放,font-size: 1.5em时图标不会等比变大 - 如果 SVG 内用了
currentColor,这里也无效——背景图是渲染快照,不参与 CSS 继承链
真正麻烦的点不在“怎么引”,而在“引完之后能不能动”。内联 SVG 的 currentColor + viewBox 是最小成本支持主题切换和响应式的组合,但很多人卡在忘记删导出 SVG 里的硬编码颜色或冗余命名空间上。



















