内联SVG是唯一支持动态变色、暗黑模式响应、hover动画及随font-size缩放的方式,必须设viewBox、用fill="currentColor"、清除子元素内联样式,并确保父容器声明color。

内嵌 SVG 和外部引入 SVG 不是“哪个更好”,而是“哪个更合适”——取决于你是否需要控制颜色、响应暗黑模式、加 hover 动画,或者图标是否复用频繁、体积是否敏感。
需要动态变色或响应暗黑模式时必须内联
只有内联 SVG 能让 fill="currentColor" 生效,从而继承父级 color 值。比如按钮文字变深色时图标自动同步变深,<img src="icon.svg"> 完全做不到。
- 必须手动清理原始 SVG:删掉所有
fill、stroke等内联属性,否则 CSS 无法覆盖 -
viewBox必须保留(如viewBox="0 0 24 24"),仅设width/height会导致缩放失真 - 加
display: block或vertical-align: middle,避免 inline 元素默认的基线对齐留白 - 导出后删掉
xmlns(HTML5 不需要)和overflow="hidden"(可能裁剪 hover 动画)
图标数量多、复用广时优先外链
当项目有 20+ 图标、跨多个页面使用、或设计资源由专人维护,外链比内联更可持续。用 <img src="home.svg"> 最轻量,浏览器缓存生效快,HTML 体积零污染。
- 本地开发报 404?大概率路径不在
public/目录下——Vite/Webpack 默认只服务该目录 - 线上部署需确认服务器返回
image/svg+xmlMIME 类型,否则会触发下载而非渲染 -
<img>引入的 SVG 是“黑盒”,svg:hover path { fill: red }无效,换色只能靠fill="currentColor"+ 父级color - 纯装饰性图标(如分隔线、背景花纹)用
background-image: url()更灵活,但无法被屏幕阅读器识别
<symbol>+<use> 复用方案常见卡点
<symbol>+<use> 是平衡复用与语义的折中选择,但落地常因三个细节失败:
立即学习“前端免费学习笔记(深入)”;
-
<symbol>必须放在文档可解析范围内(如<body>开头),不能塞进<template>或 JS 动态插入后才挂载 -
<symbol>自身不渲染,加style="display: none;"安全,但别用hidden属性(IE11 不识别) -
<use>不继承外部fill,必须在<symbol>内部的<path>上显式写fill="currentColor" - 跨域 SVG(如 CDN 上的
https://cdn.example.com/icons.svg)在部分旧浏览器中不支持<use href="...">
真正难的不是选哪种方式,而是统一清理 SVG 源文件的习惯——90% 的“图标发虚”“hover 不生效”“暗黑模式失效”,都源于直接复制 Sketch/Figma 导出的 SVG 后没删 fill、没补 viewBox、没改 currentColor。工程化管理的关键,其实是把这三步变成构建脚本里的固定动作,而不是每次手抖漏掉。



















