在SVG图形开发过程中,经常会遇到需要多次使用相同图形的场景,比如页面中的重复图标、固定样式的装饰元素等。如果每次都重新编写完整的图形代码,不仅会让SVG文件体积变大,后续修改样式时也需要逐个调整,维护成本很高。SVG提供的<use>和<symbol>标签就是专门解决这个问题的方案,两者配合可以实现高效的图形复用。

symbol标签的基础用法
<symbol>标签用于定义可复用的图形模板,它本身不会在页面中直接渲染,只有被<use>引用时才会显示。它支持设置viewBox属性来定义图形的坐标系统,这样引用时可以灵活调整显示尺寸和位置。
下面是一个定义图标的<symbol>示例:
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
<!-- 定义一个星星图形模板 -->
<symbol id="star" viewBox="0 0 24 24">
<path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z" fill="#ffcc00" stroke="#ff9900" stroke-width="1"/>
</symbol>
</svg>
这里把<svg>设置为display: none,是为了避免存放模板的SVG容器占据页面空间,只保留模板定义的作用。
use标签的基础用法
<use>标签用于引用已经定义的图形元素,既可以引用当前SVG内的<symbol>,也可以引用其他SVG文件中的元素。它的核心属性是href,用来指定被引用元素的ID,还可以通过x、y设置显示位置,width、height设置显示尺寸。
引用上面定义的星星模板的示例:
<svg width="200" height="100" xmlns="http://www.w3.org/2000/svg"> <!-- 引用星星模板,显示在(10,10)位置,尺寸为24x24 --> <use href="#star" x="10" y="10" width="24" height="24"/> <!-- 再次引用同一个模板,显示在(50,10)位置,尺寸放大到36x36 --> <use href="#star" x="50" y="10" width="36" height="36"/> <!-- 第三次引用,调整填充色 --> <use href="#star" x="100" y="10" width="24" height="24" style="fill: #ff6600;"/> </svg>
可以看到,同一个星星模板被复用了三次,只需要修改位置和样式属性就能得到不同的显示效果,不需要重复编写路径代码。
use和symbol配合使用的完整流程
实际开发中通常会把<symbol>集中定义在一个隐藏的SVG容器中,需要使用时通过<use>按需引用,流程如下:
- 第一步:定义隐藏的SVG容器,内部编写多个
<symbol>模板,每个模板设置唯一的id和合适的viewBox - 第二步:在需要显示图形的位置,编写
<svg>容器,内部使用<use>标签,通过href="#模板id"引用对应的图形 - 第三步:通过
<use>的属性或CSS调整引用图形的位置、尺寸、颜色等样式
下面是一个包含多个模板的完整示例:
<!-- 存放所有图形模板的隐藏容器 -->
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
<symbol id="circle_icon" viewBox="0 0 20 20">
<circle cx="10" cy="10" r="8" fill="#4285f4" stroke="#3367d6" stroke-width="1"/>
</symbol>
<symbol id="square_icon" viewBox="0 0 20 20">
<rect x="2" y="2" width="16" height="16" fill="#34a853" stroke="#2d9249" stroke-width="1"/>
</symbol>
</svg>
<!-- 页面中实际使用图形 -->
<div class="icon-group">
<svg width="40" height="40" xmlns="http://www.w3.org/2000/svg">
<use href="#circle_icon"/>
</svg>
<svg width="40" height="40" xmlns="http://www.w3.org/2000/svg">
<use href="#square_icon"/>
</svg>
<svg width="60" height="60" xmlns="http://www.w3.org/2000/svg">
<use href="#circle_icon" style="fill: #ea4335;"/>
</svg>
</div>
两个标签的核心差异
很多开发者会混淆<use>和<symbol>的作用,两者的核心差异如下:
| 对比项 | symbol标签 | use标签 |
|---|---|---|
| 渲染特性 | 本身不会渲染,仅作为模板存在 | 会渲染被引用的图形 |
| 核心作用 | 定义可复用的图形结构和坐标系统 | 引用已有图形并控制显示属性 |
| viewBox支持 | 支持,用于定义模板的坐标范围 | 不支持,显示时的坐标系统由引用的模板决定 |
| 使用依赖 | 需要被use引用才能显示 | 需要引用已存在的元素(包括symbol、普通图形元素等) |
注意事项
使用这两个标签时需要注意几个常见问题:
- 引用的
id必须唯一,否则会导致引用错误,图形无法正常显示 - 如果
<symbol>没有设置viewBox,引用时调整width和height可能会导致图形拉伸变形 - 修改引用图形的样式时,部分属性会覆盖模板中定义的样式,比如
fill、stroke等,具体优先级遵循CSS样式规则 - 如果需要引用外部SVG文件中的图形,
href需要写成完整路径加ID的形式,比如href="icons.svg#star",且需要注意跨域问题
总结来说,
<symbol>负责定义图形模板,<use>负责复用模板,两者配合可以大幅减少SVG代码的冗余,提升开发和维护效率,是SVG图形开发中非常实用的组合。