pin_drop当前位置:知识文库 ❯ 图文

多媒体:符号与引用 - 完整教程与代码示例

一、教程简介

SVG 提供了 <defs><symbol><use> 三个元素,用于定义可复用的图形模板和实例化引用。<defs> 定义不直接渲染的元素,<symbol> 定义可参数化的图形模板,<use> 引用并实例化已定义的元素。本教程将详细讲解这三个元素的使用方法和最佳实践。


二、核心概念

defs - 定义

<defs> 用于存放不直接渲染的定义元素,如渐变、滤镜、路径、图形模板等。只有被引用时才会渲染。

symbol - 符号

<symbol> 类似于 <g>,但有以下区别:

  • 不直接渲染:必须通过 <use> 引用

  • 独立视图:支持独立的 viewBoxpreserveAspectRatio

  • 适用场景:适合定义可复用的图标和图形模板

use - 引用

<use> 引用并实例化 <defs><symbol> 或其他元素,创建一个视觉副本。


三、语法与用法

defs

代码示例

<defs>
  <linearGradient id="myGrad">...</linearGradient>
  <filter id="myFilter">...</filter>
  <g id="myShape">
    <rect width="50" height="50" fill="red" />
  </g>
</defs>

symbol

代码示例

<symbol id="icon-home" viewBox="0 0 24 24">
  <path d="M3 12l9-9 9 9" />
  <path d="M5 10v10h14V10" />
</symbol>
属性 说明
viewBox 符号的视图框
preserveAspectRatio 宽高比保持方式
x, y, width, height 不直接使用,由 use 指定

use

代码示例

<use href="#icon-home" x="10" y="10" width="24" height="24" fill="#58a6ff" />
属性 说明
href 引用元素的 ID(现代写法)
xlink:href 引用元素的 ID(旧写法,兼容)
x, y 实例位置偏移
width, height 实例尺寸(用于 symbol)

四、代码示例

示例1:symbol/use 图标系统

代码示例

<!-- 隐藏的 SVG sprite(图标定义) -->
<svg xmlns="http://www.w3.org/2000/svg" style="display:none;">
  <symbol id="icon-search" viewBox="0 0 24 24">
    <circle cx="11" cy="11" r="8" fill="none" stroke="currentColor" stroke-width="2" />
    <path d="M21 21l-4.35-4.35" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" />
  </symbol>

  <symbol id="icon-home" viewBox="0 0 24 24">
    <path d="M3 12L12 3l9 9" fill="none" stroke="currentColor" stroke-width="2"
          stroke-linecap="round" stroke-linejoin="round" />
    <path d="M5 10v10h4v-6h6v6h4V10" fill="none" stroke="currentColor" stroke-width="2"
          stroke-linecap="round" stroke-linejoin="round" />
  </symbol>

  <symbol id="icon-heart" viewBox="0 0 24 24">
    <path d="M12 21C12 21 3 14 3 8.5 3 5.4 5.4 3 8.5 3c1.7 0 3.2.8 3.5 2
           .3-1.2 1.8-2 3.5-2C18.6 3 21 5.4 21 8.5 21 14 12 21 12 21z"
          fill="none" stroke="currentColor" stroke-width="2" stroke-linejoin="round" />
  </symbol>
</svg>

<!-- 图标使用 -->
<svg width="32" height="32"><use href="#icon-search" fill="#58a6ff" /></svg>
<svg width="32" height="32"><use href="#icon-home" fill="#3fb950" /></svg>
<svg width="32" height="32"><use href="#icon-heart" fill="#e94560" /></svg>

提示:SVG Sprite 技术将所有图标定义在一个隐藏的 SVG 中,通过 <use> 引用,大大减少代码重复,是现代图标系统的核心方案。

示例2:defs 复用与图形模板

代码示例

<svg width="700" height="350" viewBox="0 0 700 350">
  <defs>
    <!-- 可复用的渐变 -->
    <linearGradient id="btnGrad" x1="0" y1="0" x2="0" y2="1">
      <stop offset="0%" stop-color="#58a6ff" />
      <stop offset="100%" stop-color="#1f6feb" />
    </linearGradient>

    <!-- 可复用的阴影 -->
    <filter id="cardShadow">
      <feDropShadow dx="0" dy="2" stdDeviation="4"
                    flood-color="#000" flood-opacity="0.3" />
    </filter>

    <!-- 可复用的卡片模板 -->
    <g id="cardTemplate">
      <rect width="160" height="100" rx="8" fill="#1e293b"
            filter="url(#cardShadow)" />
      <rect width="160" height="4" rx="2" fill="url(#btnGrad)" y="0" />
    </g>
  </defs>

  <!-- 使用卡片模板 -->
  <use href="#cardTemplate" x="30" y="40" />
  <use href="#cardTemplate" x="220" y="40" />
  <use href="#cardTemplate" x="410" y="40" />
</svg>

五、浏览器兼容性

特性 Chrome Firefox Safari Edge IE
<defs> 1+ 1.5+ 3+ 12+ 9+
<symbol> 1+ 1.5+ 3+ 12+ 9+
<use> 1+ 1.5+ 3+ 12+ 9+
href(非 xlink) 50+ 51+ 12+ 14+ 不支持

注意:旧浏览器需要使用 xlink:href 替代 href


六、注意事项与最佳实践

1. SVG Sprite 技术

代码示例

<!-- 隐藏的 SVG sprite -->
<svg xmlns="http://www.w3.org/2000/svg" style="display:none;">
  <symbol id="icon-xxx" viewBox="0 0 24 24">...</symbol>
</svg>

<!-- 使用图标 -->
<svg><use href="#icon-xxx" /></svg>

2. href vs xlink:href

代码示例

<!-- 现代写法 -->
<use href="#myShape" />

<!-- 兼容写法 -->
<use xlink:href="#myShape" />

<!-- 两者都写(最兼容) -->
<use href="#myShape" xlink:href="#myShape" />

3. use 创建的是 Shadow DOM 副本

<use> 创建的副本在 Shadow DOM 中,无法直接通过 CSS 修改内部元素样式,但可以修改继承属性(如 fill、stroke)。

4. symbol 的 viewBox

代码示例

<!-- symbol 定义 viewBox -->
<symbol id="icon" viewBox="0 0 24 24">
  <path d="..." />
</symbol>

<!-- use 指定显示尺寸 -->
<use href="#icon" width="32" height="32" />

5. 避免循环引用

<use> 不能引用自身或形成循环引用链。


七、代码规范示例

代码示例

<!-- 推荐:SVG Sprite 文件结构 -->
<svg xmlns="http://www.w3.org/2000/svg" style="display:none;">
  <!-- 图标:搜索 -->
  <symbol id="icon-search" viewBox="0 0 24 24">
    <circle cx="11" cy="11" r="8" fill="none" stroke="currentColor" stroke-width="2" />
    <path d="M21 21l-4.35-4.35" fill="none" stroke="currentColor"
          stroke-width="2" stroke-linecap="round" />
  </symbol>

  <!-- 图标:主页 -->
  <symbol id="icon-home" viewBox="0 0 24 24">
    <path d="M3 12L12 3l9 9" fill="none" stroke="currentColor" stroke-width="2"
          stroke-linecap="round" stroke-linejoin="round" />
    <path d="M5 10v10h4v-6h6v6h4V10" fill="none" stroke="currentColor" stroke-width="2"
          stroke-linecap="round" stroke-linejoin="round" />
  </symbol>
</svg>

<!-- 推荐:使用 currentColor 方便主题切换 -->
<svg width="24" height="24" style="color: #58a6ff;">
  <use href="#icon-search" />
</svg>

八、常见问题与解决方案

常见问题

use 引用的元素无法修改样式?

<use> 创建的是 Shadow DOM 副本,内部样式不可直接覆盖。使用 currentColor 或 CSS 变量解决:

代码示例

<!-- symbol 中使用 currentColor -->
<symbol id="icon" viewBox="0 0 24 24">
  <circle r="10" fill="currentColor" />
</symbol>

<!-- 使用时通过 color 属性控制颜色 -->
<svg style="color: red;"><use href="#icon" /></svg>
如何引用外部 SVG 文件中的 symbol?

使用 href 指定外部文件路径和 symbol ID:

代码示例

<!-- 引用外部 SVG 文件中的 symbol -->
<use href="icons.svg#icon-search" />
use 引用后位置偏移?

<use>xy 属性会偏移引用内容的坐标系。确保 symbol 中的图形从 (0,0) 开始绘制即可解决。

defs、symbol、g 三者有什么区别?

<defs> 是容器,存放不直接渲染的元素;<symbol> 是模板,支持独立 viewBox,必须通过 use 引用;<g> 是分组,直接渲染,不支持独立 viewBox。图标系统推荐使用 symbol。

如何让 use 引用的图标支持不同颜色?

在 symbol 定义中使用 currentColor 作为填充或描边颜色,使用时通过父 SVG 的 color 属性或 fill 属性控制颜色。


九、总结

SVG 符号与引用是构建可复用图形系统的核心机制,关键要点:

  • defs:定义不直接渲染的元素,如渐变、滤镜、模板

  • symbol:定义可参数化的图形模板,支持独立 viewBox

  • use:引用并实例化已定义的元素

  • SVG Sprite:使用 symbol + use 构建图标系统

  • currentColor:使用 currentColor 方便主题切换

  • Shadow DOM:use 创建的副本在 Shadow DOM 中

  • href 兼容性:旧浏览器需使用 xlink:href

下一教程将介绍 SVG 与 Canvas 的全面对比。

标签: SVG符号 symbol标签 use引用 defs定义 SVG Sprite 图标系统

本文涉及AI创作

内容由AI创作,请仔细甄别

list快速访问

上一篇: 多媒体:剪辑与遮罩 - 完整教程与代码示例 下一篇: 多媒体:SVG与Canvas对比 - 完整教程与代码示例

poll相关推荐