Skip to content

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 的劣势

劣势说明
无法操作 DOMJavaScript 无法访问 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 文件中的 fillstroke 使用 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 基本结构

参考链接