pin_drop当前位置:知识文库 ❯ 图文
多媒体:符号与引用 - 完整教程与代码示例
一、教程简介
SVG 提供了 <defs>、<symbol> 和 <use> 三个元素,用于定义可复用的图形模板和实例化引用。<defs> 定义不直接渲染的元素,<symbol> 定义可参数化的图形模板,<use> 引用并实例化已定义的元素。本教程将详细讲解这三个元素的使用方法和最佳实践。
二、核心概念
defs - 定义
<defs> 用于存放不直接渲染的定义元素,如渐变、滤镜、路径、图形模板等。只有被引用时才会渲染。
symbol - 符号
<symbol> 类似于 <g>,但有以下区别:
-
不直接渲染:必须通过
<use>引用 -
独立视图:支持独立的
viewBox和preserveAspectRatio -
适用场景:适合定义可复用的图标和图形模板
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>use
代码示例
<use href="#icon-home" x="10" y="10" width="24" height="24" fill="#58a6ff" />四、代码示例
示例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>五、浏览器兼容性
注意:旧浏览器需要使用
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> 的 x 和 y 属性会偏移引用内容的坐标系。确保 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 的全面对比。
本文涉及AI创作
内容由AI创作,请仔细甄别