img 嵌入 SVG
通过 <img> 标签引入外部 SVG 文件是最简单的 SVG 使用方式。与内联 SVG 相比,这种方式更简洁,但也丧失了一些优势。本节将对比这两种方式的优缺点,帮助你做出选择。
前置知识
阅读本节前,建议先了解:SVG 与 canvas 对比
基础概念
通过 <img> 标签嵌入 SVG 文件是使用 SVG 的三种主要方式之一(另外两种是内联 SVG 和 CSS 背景)。<img src="file.svg" 将 SVG 作为外部资源加载,浏览器将其渲染为图像。
这种方式最简单,但 SVG 的内容无法被 JavaScript 直接操作,也无法被 CSS 选择器单独样式化。
语法
基本用法
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>img 嵌入 SVG</title>
</head>
<body>
<h1>img 嵌入 SVG</h1>
<!-- 最简单的用法 -->
<img src="logo.svg" alt="公司 Logo" width="120" height="40">
<hr>
<!-- SVG 作为图片链接 -->
<a href="/home">
<img src="home-icon.svg" alt="首页" width="24" height="24">
</a>
<hr>
<!-- CSS 控制尺寸 -->
<img src="chart.svg" alt="图表" style="width: 100%; max-width: 600px; height: auto;">
</body>
</html>详细说明
img 嵌入 SVG 的优势
| 优势 | 说明 |
|---|---|
| 简洁 | HTML 代码最简单 |
| 缓存 | 浏览器可以单独缓存 SVG 文件 |
| 可复用 | 同一 SVG 可在多处引用 |
| 体积小 | HTML 文件不膨胀 |
| CSS 属性 | 可用 CSS 控制 width/height/object-fit 等 |
img 嵌入 SVG 的劣势
| 劣势 | 说明 |
|---|---|
| 无法操作 DOM | JavaScript 无法访问 SVG 内部元素 |
| 无法单独样式化 | CSS 无法选中 SVG 内部的特定元素 |
| 无法交互 | SVG 内部的链接、动画等可能失效 |
| 颜色控制有限 | 不能使用 currentColor 以外的动态颜色 |
| 无障碍受限 | alt 属性是唯一的文本替代 |
与内联 SVG 的详细对比
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>对比</title>
<style>
/* img SVG:只能整体控制 */
.logo-img {
width: 120px;
height: auto;
filter: drop-shadow(0 2px 4px rgba(0,0,0,0.2));
}
/* 内联 SVG:可以控制内部元素 */
.logo-inline .icon-path {
fill: #4285f4;
transition: fill 0.3s;
}
.logo-inline:hover .icon-path {
fill: #1a73e8;
}
</style>
</head>
<body>
<h1>img SVG vs 内联 SVG</h1>
<h2>img 嵌入(外部文件)</h2>
<img src="logo.svg" alt="Logo" class="logo-img">
<h2>内联 SVG</h2>
<svg class="logo-inline" width="120" height="40" viewBox="0 0 120 40">
<path class="icon-path" d="M10 30 L40 10 L70 30 Z" fill="#4285f4"/>
<text x="80" y="28" font-size="14" fill="#333">Brand</text>
</svg>
<!-- hover 内联 SVG 时,路径颜色会变化 -->
<!-- hover img SVG 时,不会有内部颜色变化 -->
</body>
</html>currentColor 的使用
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>currentColor</title>
<style>
/* CSS color 属性决定 currentColor 的值 */
.icon-blue { color: #4285f4; }
.icon-red { color: #ea4335; }
.icon-lg { width: 48px; height: 48px; }
</style>
</head>
<body>
<h1>currentColor 技巧</h1>
<!--
SVG 文件中使用 currentColor 代替固定颜色:
<svg viewBox="0 0 24 24">
<path fill="currentColor" d="M12 2..."/>
</svg>
这样 img SVG 的颜色可以通过 CSS color 控制
-->
<!-- 蓝色图标 -->
<img src="icon.svg" alt="图标" class="icon-blue icon-lg">
<!-- 红色图标(同一 SVG 文件,不同颜色) -->
<img src="icon.svg" alt="图标" class="icon-red icon-lg">
</body>
</html>currentColor
如果 SVG 文件中的 fill 和 stroke 使用 currentColor,那么通过 <img> 嵌入时,可以用 CSS 的 color 属性控制 SVG 的颜色。这是 <img> 嵌入 SVG 时最常用的颜色控制技巧。
SVG 作为 CSS 背景
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>CSS 背景 SVG</title>
<style>
.bg-icon {
width: 32px;
height: 32px;
/* SVG 作为背景图 */
background-image: url('icon.svg');
background-size: contain;
background-repeat: no-repeat;
display: inline-block;
}
</style>
</head>
<body>
<h1>SVG 作为 CSS 背景</h1>
<span class="bg-icon"></span> 列表项
</body>
</html>实战示例
SVG 图标系统
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>SVG 图标系统</title>
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
padding: 20px;
}
/* 图标基础样式 */
.icon {
display: inline-block;
width: 24px;
height: 24px;
vertical-align: middle;
}
/* 通过 CSS color 控制颜色 */
.icon-nav { color: #4285f4; }
.icon-alert { color: #ea4335; }
.icon-success { color: #34a853; }
.icon-muted { color: #999; }
/* 悬停效果 */
.icon-hover {
cursor: pointer;
transition: color 0.2s;
}
.icon-hover:hover {
color: #1a73e8;
}
</style>
</head>
<body>
<h1>导航</h1>
<nav>
<!-- 使用 img 嵌入 SVG 图标 -->
<a href="/home" style="display: inline-flex; align-items: center; gap: 8px; margin-right: 16px;">
<img src="icon-home.svg" alt="首页" class="icon icon-nav icon-hover">
<span>首页</span>
</a>
<a href="/settings" style="display: inline-flex; align-items: center; gap: 8px; margin-right: 16px;">
<img src="icon-settings.svg" alt="设置" class="icon icon-nav icon-hover">
<span>设置</span>
</a>
</nav>
<h1>状态指示</h1>
<ul>
<li style="display: flex; align-items: center; gap: 8px; margin-bottom: 8px;">
<img src="icon-check.svg" alt="成功" class="icon icon-success"> 操作成功
</li>
<li style="display: flex; align-items: center; gap: 8px; margin-bottom: 8px;">
<img src="icon-warning.svg" alt="警告" class="icon icon-alert"> 请注意
</li>
<li style="display: flex; align-items: center; gap: 8px;">
<img src="icon-info.svg" alt="信息" class="icon icon-muted"> 提示信息
</li>
</ul>
</body>
</html>注意事项
<img>嵌入的 SVG 中<script>不会执行<img>嵌入的 SVG 中外部资源可能被阻止加载- SVG 中的
<a>链接在<img>中无法点击 - SVG 中的 CSS 动画在
<img>中可能受限 - 使用
<object>嵌入 SVG 可以保留部分交互功能
最佳实践
- 静态图标和 Logo 使用
<img src="file.svg"> - SVG 文件中使用
currentColor实现颜色可定制 - 需要交互的 SVG 使用内联 SVG 或
<object> - 重复使用的图标使用
<img>以利用浏览器缓存 - 提供合适的
alt文本和width/height属性
下一节
继续学习:table 基本结构