携手开启这个充满创意和挑战的旅程吧!一同探索 SVG 图标设计的奥秘,为我们的项目带来新的活力和灵感!
在当今的数字时代,图标已经成为现代 Web 应用和网站中不可或缺的一部分,同时也是设计系统中不可或缺的组成部分。你可能会好奇,为什么要创建图标系统呢?我们从以下几个方面来回答这个问题:
因此,创建一个图标系统不仅能够提升用户体验、增强品牌形象,还能够提高设计效率和一致性,为设计团队和开发团队带来诸多好处。通过统一管理和维护图标资源,可以实现设计和开发的无缝协作,为用户提供更加流畅和愉悦的在线体验。
一个完善的图标系统不仅仅是一组图标的简单集合,而是由多个关键部分组成的复杂系统。其中,设计规范、图标制作工作、图标库、字体生成器、图标导出和管理系统、以及图标集成和使用指南等几个关键组成部分相辅相成,共同确保图标在设计、管理和应用过程中保持一致性、易用性和高效性。
正如你所见,一个完善的图标系统包括设计规范、图标制作工具、流程、图标库、字体生成器以及集成到 Web 应用中等组成部分。它们共同为设计团队和开发团队提供了一致、高效、易用的图标资源和使用方式,从而促进了设计和开发工作的协作和创造。然而,在本课程中,将聚焦于图标的设计和获取,特别是探讨如何将图标系统无缝集成到 Web 应用中。
假设你正在或需要构建一个图标系统。这个系统必须具备非规定性、可扩展性,并且能够通过 CSS 或 JavaScript 进行动态编辑。这些图标将被多个团队在许多不同的 Web 应用程序或网站中使用,而且这些应用程序和网站可能使用不同的框架和技术构建。在应用图标时,它们需要具有可重新样式化、可缓存,并且在添加更多图标时能够快速、轻松地进行更新。用一句话来概括,“图标系统需要极度灵活”。
在处理图标系统时,基本上我们有三个选择:字体图标(Icon Fonts)、CSS 数据 URI(Data URI)和 SVG 图标。讨论最多的还是字体图标和 SVG 图标。SVG成为优秀的图标系统的原因很多:
SVG 图标具有灵活性、清晰度、小文件大小、可编辑性、动态性、可搜索性和跨平台兼容性等诸多优势,使其成为现代 Web 设计中的理想选择。
一旦你选择了使用 SVG 图标而非字体图标,就需要思考如何优化图标的交付,以及加速图标的创建和使用速度。可以利用 SVG 雪碧图技术来做到这一点。稍后我们会与大家一起探讨创建 SVG 雪碧图的多种方式(至少三种)。尽管它们在外观或工作方式上略有不同,但其基本概念几乎相同。
现如今,获得 SVG 图标有多种途径,首先从设计师团队获得,其次从第三方图标库获得。如果你想自己从头开始设计图标,这并不是件易事。你需要制定一些规则和流程,它可能会因团队不同而略有差异。
以阿里妈妈的 Iconfont 为例。首先,你需要有一个统一的模板,比如图标在绘制时均以标准图标大小 1024 x 1024 绘制,因为在制作图标时需要设置较高的清晰度,所以图标路径也需要等比例放大。其次,你可以直接将画好的图标路径复制到模板里,根据模板的辅助线,对图标进行位置的调节,居中,四周等距,保证图标的统一性。
在绘制图标时,还需要注意一些细节。
完成图标设计后,你可以从设计工具中导出 SVG 文件。然而,需要注意的是,不同的设计工具可能会导致 SVG 文件存在一些多余的标记和元素数据。有时候,路径数据可能会过于精确,导致 SVG 文件体积过大。为了优化 SVG 代码,建议使用诸如 SVGOMG 等工具进行处理。
如果你不是一名专业的 Web 设计师(仅是一名专业的 Web 开发者),要亲手设计 SVG 图标着实困难,那么你可以考虑通过第三方图标库(例如 FontAwesome、Flowbite、IconScout、FlatIcon、Icons8、LineIcons、IconFiner、css.gg 和 Iconfont 等)获取相关 SVG 图标。我通常在 Iconfont 和 FontAwesome 平台上获取图标。
为了便于后续能更好的向大家演示,我从 FontAwesome 平台上下载了一些 SVG 图标,并且统一放在名为 icons 文件夹中:
注意,在 icons 中的每个 SVG 图标都是一个独立的 .svg 文件。
一旦准备好 SVG 图标文件并将它们放置在一个文件夹中(如 icons),你就拥有了自己的图标库。随后,你可以根据需要不断向 icons 文件夹中添加新的 SVG 图标。接下来,将重点讨论如何将现有的SVG图标应用于Web应用或网站。
接下来的内容会涉及 SVG 编码的实践阶段,你需要了解一些 SVG 基础知识,并能够阅读和理解简单 SVG 文件的结构。理想情况下,你应该了解以下内容:
<line> 、<rect> 、<circle> 、<ellipse> 、<polyline> 、<polygon> 和 <path><g> 、<symbol> 、<defs> 、<use>fill 、stroke 和 stroke-width有了这些先决条件,开始学习如何创建 SVG 雪碧图,即将 SVG 图标应用到 Web 应用或网站!
由于 SVG 是 XML 代码,它可以内联方式嵌入到 HTML 文档中,作为一段代码存在。嵌入的 <svg> 元素将作为所有图标的容器,并将成为我们要使用的 SVG 雪碧图。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SVG Sprites</title>
</head>
<body>
<svg class="sr-only">
<!-- SVG 图标放在这里 -->
</svg>
</body>
</html>接下来,在 <svg> 元素中为每个图创建一个 <symbol> 元素,每个 <symbol> 必须有一个 id 名,这外名称最好与 icons 文件夹中的 .svg 文件同名,例如 id="twitter" 对应着 icons 文件夹中的 twitter.svg 。
<svg class="sr-only">
<!-- Twitter -->
<symbol id="twitter">
<!-- 绘制 Twitter 图标的内容放在这里 -->
</symbol>
</svg> 使用文本编辑器,打开 icons 文件夹中的 twitter.svg 文件,其对应的 SVG 代码如下:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.-->
<path d="M459.4 151.7c.3 4.5 .3 9.1 .3 13.6 0 138.7-105.6 298.6-298.6 298.6-59.5 0-114.7-17.2-161.1-47.1 8.4 1 16.6 1.3 25.3 1.3 49.1 0 94.2-16.6 130.3-44.8-46.1-1-84.8-31.2-98.1-72.8 6.5 1 13 1.6 19.8 1.6 9.4 0 18.8-1.3 27.6-3.6-48.1-9.7-84.1-52-84.1-103v-1.3c14 7.8 30.2 12.7 47.4 13.3-28.3-18.8-46.8-51-46.8-87.4 0-19.5 5.2-37.4 14.3-53 51.7 63.7 129.3 105.3 216.4 109.8-1.6-7.8-2.6-15.9-2.6-24 0-57.8 46.8-104.9 104.9-104.9 30.2 0 57.5 12.7 76.7 33.1 23.7-4.5 46.5-13.3 66.6-25.3-7.8 24.4-24.4 44.8-46.1 57.8 21.1-2.3 41.6-8.1 60.4-16.2-14.3 20.8-32.2 39.3-52.6 54.3z"/>
</svg>我们只需要将绘制“Twitter”图标形状的部分(上面代码中的 <path> )嵌入到 id 名为 twitter 的 <symbol> 元素中:
<svg class="sr-only">
<!-- Twitter -->
<symbol id="twitter">
<path d="M459.4 151.7c.3 4.5 .3 9.1 .3 13.6 0 138.7-105.6 298.6-298.6 298.6-59.5 0-114.7-17.2-161.1-47.1 8.4 1 16.6 1.3 25.3 1.3 49.1 0 94.2-16.6 130.3-44.8-46.1-1-84.8-31.2-98.1-72.8 6.5 1 13 1.6 19.8 1.6 9.4 0 18.8-1.3 27.6-3.6-48.1-9.7-84.1-52-84.1-103v-1.3c14 7.8 30.2 12.7 47.4 13.3-28.3-18.8-46.8-51-46.8-87.4 0-19.5 5.2-37.4 14.3-53 51.7 63.7 129.3 105.3 216.4 109.8-1.6-7.8-2.6-15.9-2.6-24 0-57.8 46.8-104.9 104.9-104.9 30.2 0 57.5 12.7 76.7 33.1 23.7-4.5 46.5-13.3 66.6-25.3-7.8 24.4-24.4 44.8-46.1 57.8 21.1-2.3 41.6-8.1 60.4-16.2-14.3 20.8-32.2 39.3-52.6 54.3z" />
</symbol>
</svg> <symbol> 可以有自己的 viewBox 属性,这使得在任何时候都可以控制它的内容在其容器内的位置。因此,使用 <symbol> 元素实例化 icons 中每个 SVG 图标时,应该将相应图标的 viewBox 属性值复制给 <symbol> 元素。例如,上面示例中的“Twitter”图标(twitter.svg),它的 <svg> 元素的 viewBox 的值为 0 0 512 512 ,因此,我们应该将该值赋予给 <symbol> 元素的 viewBox 属性:
<svg class="sr-only">
<!-- Twitter -->
<symbol id="twitter" viewBox="0 0 512 512">
<path d="M459.4 151.7c.3 4.5 .3 9.1 .3 13.6 0 138.7-105.6 298.6-298.6 298.6-59.5 0-114.7-17.2-161.1-47.1 8.4 1 16.6 1.3 25.3 1.3 49.1 0 94.2-16.6 130.3-44.8-46.1-1-84.8-31.2-98.1-72.8 6.5 1 13 1.6 19.8 1.6 9.4 0 18.8-1.3 27.6-3.6-48.1-9.7-84.1-52-84.1-103v-1.3c14 7.8 30.2 12.7 47.4 13.3-28.3-18.8-46.8-51-46.8-87.4 0-19.5 5.2-37.4 14.3-53 51.7 63.7 129.3 105.3 216.4 109.8-1.6-7.8-2.6-15.9-2.6-24 0-57.8 46.8-104.9 104.9-104.9 30.2 0 57.5 12.7 76.7 33.1 23.7-4.5 46.5-13.3 66.6-25.3-7.8 24.4-24.4 44.8-46.1 57.8 21.1-2.3 41.6-8.1 60.4-16.2-14.3 20.8-32.2 39.3-52.6 54.3z" />
</symbol>
</svg> 如果你的图标库中的所有 SVG 图标都是按同一标准和尺寸设计的,你可以忽略 <symbol> 元素上的 viewBox 属性的设置。要是你图标库中的 SVG 图标并没有遵循统一标准设计,而是从不同平台上获取的 SVG 图标,那么每个图标的尺寸就会有所差异。例如, FontAwesome 平台上的图标的 <svg> 元素的 viewBox 属性值普遍都是 0 0 512 512 ,而 iconfont 平台上的图标的 <svg> 元素的 viewBox 属性值普遍都是 0 0 1024 1024 :
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg t="1711789057624" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4354" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200">
<path d="M350.65 447.74c7.22-13.06 21.02-21.18 35.97-21.18l1.75 0.04c15.13 0.5 28.87 9.53 35.49 23.55l40 84.85 61.48-156.37c6.17-15.76 21.11-26 38.06-26.1 17.04 0 32 10.06 38.35 25.61l40.96 100.61 20.43-20.83c8.12-8.25 18.99-12.49 30.41-12.32 11.27 0.25 22.12 5.26 29.67 13.72l47.05 52.64h33.44c9.26-13.67 17.61-27.82 24.51-42.4 30.42-64.23 23.59-130.04-22.05-186.44-41.53-51.33-121.95-71.79-187.05-45.57-38.15 15.37-71.97 41.49-112.01 65.31-2.23-1.97-7.78-7.31-13.78-12.1-31.19-24.89-62.45-50.17-102.81-58.46-91.81-18.88-202.64 20.66-210.51 151.13-2.68 44.39 8.82 83.01 29.19 117.41h111.92l29.53-53.1z" p-id="4355"></path>
<path d="M691.82 517.5l-27.12 27.65c-9.74 9.92-23.68 14.23-37.33 11.57-13.68-2.69-24.96-11.99-30.19-24.89l-33.2-81.55-60.08 152.79a41.117 41.117 0 0 1-36.97 26.08l-1.37 0.03c-16.08 0-30.34-9.06-37.2-23.63l-43.27-91.79-15.61 28.09a41.164 41.164 0 0 1-35.97 21.18h-74.56c74.41 74.49 151.59 146.23 227.63 219.09 21.93 21.02 29.11 21.07 51.4-0.32 71.87-68.95 145.17-136.51 214.65-207.78 0.22-0.22 0.43-0.45 0.64-0.67-8.83-1.67-16.99-6.11-23.08-12.9l-38.37-42.95z" p-id="4356"></path>
<path d="M465.11 607.07c-7.45 0-13.99-4.14-17.19-10.93l-60.77-128.89c-0.08-0.18-0.28-0.6-0.94-0.62-0.58 0.09-0.88 0.39-0.98 0.56l-35.51 63.93c-3.36 6.04-9.74 9.8-16.65 9.8H186.22c-4.96 0-8.99-4.02-8.99-8.99 0-4.96 4.02-8.99 8.99-8.99h146.84c0.39 0 0.75-0.21 0.94-0.55l35.51-63.93c3.38-6.09 9.72-9.8 16.64-9.8 0.22 0 0.44 0 0.65 0.01 7.18 0.24 13.54 4.42 16.6 10.92l60.76 128.89c0.09 0.21 0.31 0.56 1.01 0.62 0.71-0.02 0.89-0.47 0.97-0.68l79.31-201.7c2.86-7.29 9.78-12.03 17.61-12.08h0.12c7.79 0 14.7 4.65 17.64 11.87l53.03 130.24c0.05 0.13 0.22 0.54 0.79 0.65 0.56 0.11 0.87-0.2 0.98-0.3l42.85-43.69c3.68-3.75 8.65-5.84 14.05-5.7 5.24 0.12 10.26 2.44 13.76 6.35l53.34 59.67c0.28 0.13 0.53 0.23 0.81 0.36h65.59c4.96 0 8.99 4.02 8.99 8.99 0 4.96-4.02 8.99-8.99 8.99h-65.59c-5.42 0-10.59-2.31-14.2-6.35l-53.34-59.68c-0.2-0.23-0.47-0.35-0.78-0.36-0.16 0.06-0.58 0.1-0.8 0.32l-42.84 43.69c-4.51 4.59-10.95 6.6-17.28 5.35a19.009 19.009 0 0 1-13.96-11.51L564.2 393.29c-0.09-0.24-0.35-0.69-1.01-0.67-0.73 0-0.9 0.45-0.99 0.68L482.89 595c-2.83 7.19-9.38 11.81-17.1 12.07h-0.68z" p-id="4357"></path>
</svg>这种情形之下,如果不在 <symbol> 元素上定义 viewBox 属性,那么在页面的其他位置使用 SVG 的 <use> 元素引用 <symbol> 需要指定 viewBox ,否则 SVG 图标不会如你预期的那样呈现:
<!-- 未显式设置 viewBox -->
<svg class="icon" >
<use href="#twitter" />
</svg>
<svg class="icon" >
<use href="#heart" />
</svg>
<!-- viewBox 值来自于 twitter.svg 的 viewBox -->
<svg class="icon" viewBox="0 0 512 512">
<use href="#twitter" />
</svg>
<svg class="icon" viewBox="0 0 512 512">
<use href="#heart" />
</svg>
<!-- viewBox 值来自于 heart.svg 的 viewBox -->
<svg class="icon" viewBox="0 0 1024 1024">
<use href="#twitter" />
</svg>
<svg class="icon" viewBox="0 0 1024 1024">
<use href="#heart" />
</svg>
<!-- viewBox 值来自于 twitter.svg 的 viewBox -->
<svg class="icon" viewBox="0 0 512 512">
<use href="#twitter" />
</svg>
<!-- viewBox 值来自于 heart.svg 的 viewBox -->
<svg class="icon" viewBox="0 0 1024 1024">
<use href="#heart" />
</svg>反过来则截然不同:
这也是我为什么强调,在使用 <symbol> 实例化 SVG 图标时,应该显式设置 viewBox 属性的值,并且要与对应 .svg 文件的根元素的 <svg> 元素的 viewBox 属性值保持一致。
如果手工创建 SVG 图标,这里有一个小技巧。你可以使用诸如 SVGOMG 工具对 icons 文件夹中的 SVG 图标进行优化,只保留 viewBox 属性和必要的数据(绘制图形所需的数据)。以 heart.svg 为例,优化后的代码如下:
<svg class="icon" viewBox="0 0 1024 1024">
<path d="M350.65 447.74c7.22-13.06 21.02-21.18 35.97-21.18l1.75.04c15.13.5 28.87 9.53 35.49 23.55l40 84.85 61.48-156.37c6.17-15.76 21.11-26 38.06-26.1 17.04 0 32 10.06 38.35 25.61l40.96 100.61 20.43-20.83c8.12-8.25 18.99-12.49 30.41-12.32 11.27.25 22.12 5.26 29.67 13.72l47.05 52.64h33.44c9.26-13.67 17.61-27.82 24.51-42.4 30.42-64.23 23.59-130.04-22.05-186.44-41.53-51.33-121.95-71.79-187.05-45.57-38.15 15.37-71.97 41.49-112.01 65.31-2.23-1.97-7.78-7.31-13.78-12.1-31.19-24.89-62.45-50.17-102.81-58.46-91.81-18.88-202.64 20.66-210.51 151.13-2.68 44.39 8.82 83.01 29.19 117.41h111.92l29.53-53.1z"/>
<path d="m691.82 517.5-27.12 27.65c-9.74 9.92-23.68 14.23-37.33 11.57-13.68-2.69-24.96-11.99-30.19-24.89l-33.2-81.55-60.08 152.79a41.117 41.117 0 0 1-36.97 26.08l-1.37.03c-16.08 0-30.34-9.06-37.2-23.63l-43.27-91.79-15.61 28.09a41.164 41.164 0 0 1-35.97 21.18h-74.56c74.41 74.49 151.59 146.23 227.63 219.09 21.93 21.02 29.11 21.07 51.4-.32 71.87-68.95 145.17-136.51 214.65-207.78.22-.22.43-.45.64-.67-8.83-1.67-16.99-6.11-23.08-12.9l-38.37-42.95z"/>
<path d="M465.11 607.07c-7.45 0-13.99-4.14-17.19-10.93l-60.77-128.89c-.08-.18-.28-.6-.94-.62-.58.09-.88.39-.98.56l-35.51 63.93c-3.36 6.04-9.74 9.8-16.65 9.8H186.22c-4.96 0-8.99-4.02-8.99-8.99 0-4.96 4.02-8.99 8.99-8.99h146.84c.39 0 .75-.21.94-.55l35.51-63.93c3.38-6.09 9.72-9.8 16.64-9.8.22 0 .44 0 .65.01 7.18.24 13.54 4.42 16.6 10.92l60.76 128.89c.09.21.31.56 1.01.62.71-.02.89-.47.97-.68l79.31-201.7c2.86-7.29 9.78-12.03 17.61-12.08h.12c7.79 0 14.7 4.65 17.64 11.87l53.03 130.24c.05.13.22.54.79.65.56.11.87-.2.98-.3l42.85-43.69c3.68-3.75 8.65-5.84 14.05-5.7 5.24.12 10.26 2.44 13.76 6.35l53.34 59.67c.28.13.53.23.81.36h65.59c4.96 0 8.99 4.02 8.99 8.99 0 4.96-4.02 8.99-8.99 8.99h-65.59c-5.42 0-10.59-2.31-14.2-6.35l-53.34-59.68c-.2-.23-.47-.35-.78-.36-.16.06-.58.1-.8.32l-42.84 43.69c-4.51 4.59-10.95 6.6-17.28 5.35a19.009 19.009 0 0 1-13.96-11.51L564.2 393.29c-.09-.24-.35-.69-1.01-.67-.73 0-.9.45-.99.68L482.89 595c-2.83 7.19-9.38 11.81-17.1 12.07h-.68z"/>
</svg>你可以直接将优化后的代码嵌套到 svg.sr-only 中,并把 <svg> 元素替换成 <symbol> ,同时把 class 换成与文件同名的 id :
<svg class="sr-only">
<!-- Twitter -->
<symbol id="twitter" viewBox="0 0 512 512">
<path d="M459.4 151.7c.3 4.5 .3 9.1 .3 13.6 0 138.7-105.6 298.6-298.6 298.6-59.5 0-114.7-17.2-161.1-47.1 8.4 1 16.6 1.3 25.3 1.3 49.1 0 94.2-16.6 130.3-44.8-46.1-1-84.8-31.2-98.1-72.8 6.5 1 13 1.6 19.8 1.6 9.4 0 18.8-1.3 27.6-3.6-48.1-9.7-84.1-52-84.1-103v-1.3c14 7.8 30.2 12.7 47.4 13.3-28.3-18.8-46.8-51-46.8-87.4 0-19.5 5.2-37.4 14.3-53 51.7 63.7 129.3 105.3 216.4 109.8-1.6-7.8-2.6-15.9-2.6-24 0-57.8 46.8-104.9 104.9-104.9 30.2 0 57.5 12.7 76.7 33.1 23.7-4.5 46.5-13.3 66.6-25.3-7.8 24.4-24.4 44.8-46.1 57.8 21.1-2.3 41.6-8.1 60.4-16.2-14.3 20.8-32.2 39.3-52.6 54.3z" />
</symbol>
<!-- Heart -->
<symbol id="heart" viewBox="0 0 1024 1024">
<path d="M350.65 447.74c7.22-13.06 21.02-21.18 35.97-21.18l1.75.04c15.13.5 28.87 9.53 35.49 23.55l40 84.85 61.48-156.37c6.17-15.76 21.11-26 38.06-26.1 17.04 0 32 10.06 38.35 25.61l40.96 100.61 20.43-20.83c8.12-8.25 18.99-12.49 30.41-12.32 11.27.25 22.12 5.26 29.67 13.72l47.05 52.64h33.44c9.26-13.67 17.61-27.82 24.51-42.4 30.42-64.23 23.59-130.04-22.05-186.44-41.53-51.33-121.95-71.79-187.05-45.57-38.15 15.37-71.97 41.49-112.01 65.31-2.23-1.97-7.78-7.31-13.78-12.1-31.19-24.89-62.45-50.17-102.81-58.46-91.81-18.88-202.64 20.66-210.51 151.13-2.68 44.39 8.82 83.01 29.19 117.41h111.92l29.53-53.1z"/>
<path d="m691.82 517.5-27.12 27.65c-9.74 9.92-23.68 14.23-37.33 11.57-13.68-2.69-24.96-11.99-30.19-24.89l-33.2-81.55-60.08 152.79a41.117 41.117 0 0 1-36.97 26.08l-1.37.03c-16.08 0-30.34-9.06-37.2-23.63l-43.27-91.79-15.61 28.09a41.164 41.164 0 0 1-35.97 21.18h-74.56c74.41 74.49 151.59 146.23 227.63 219.09 21.93 21.02 29.11 21.07 51.4-.32 71.87-68.95 145.17-136.51 214.65-207.78.22-.22.43-.45.64-.67-8.83-1.67-16.99-6.11-23.08-12.9l-38.37-42.95z"/>
<path d="M465.11 607.07c-7.45 0-13.99-4.14-17.19-10.93l-60.77-128.89c-.08-.18-.28-.6-.94-.62-.58.09-.88.39-.98.56l-35.51 63.93c-3.36 6.04-9.74 9.8-16.65 9.8H186.22c-4.96 0-8.99-4.02-8.99-8.99 0-4.96 4.02-8.99 8.99-8.99h146.84c.39 0 .75-.21.94-.55l35.51-63.93c3.38-6.09 9.72-9.8 16.64-9.8.22 0 .44 0 .65.01 7.18.24 13.54 4.42 16.6 10.92l60.76 128.89c.09.21.31.56 1.01.62.71-.02.89-.47.97-.68l79.31-201.7c2.86-7.29 9.78-12.03 17.61-12.08h.12c7.79 0 14.7 4.65 17.64 11.87l53.03 130.24c.05.13.22.54.79.65.56.11.87-.2.98-.3l42.85-43.69c3.68-3.75 8.65-5.84 14.05-5.7 5.24.12 10.26 2.44 13.76 6.35l53.34 59.67c.28.13.53.23.81.36h65.59c4.96 0 8.99 4.02 8.99 8.99 0 4.96-4.02 8.99-8.99 8.99h-65.59c-5.42 0-10.59-2.31-14.2-6.35l-53.34-59.68c-.2-.23-.47-.35-.78-.36-.16.06-.58.1-.8.32l-42.84 43.69c-4.51 4.59-10.95 6.6-17.28 5.35a19.009 19.009 0 0 1-13.96-11.51L564.2 393.29c-.09-.24-.35-.69-1.01-.67-.73 0-.9.45-.99.68L482.89 595c-2.83 7.19-9.38 11.81-17.1 12.07h-.68z"/>
</symbol>
</svg>其他图标重复以上步骤。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SVG Sprites</title>
</head>
<body>
<svg class="sr-only">
<symbol viewBox="0 0 448 512" id="dribbble">
<path d="M165.9 132.5c-38.3 18-66.8 53.3-75.7 95.7c6.1 .1 62.4 .3 126.4-16.7c-22.7-40.2-47.1-74.1-50.7-79zm26.1-9.1c3.8 5.1 28.6 38.9 51 80c48.6-18.3 69.1-45.9 71.6-49.4C281 124.2 235.3 112.9 192 123.4zM277.4 382c-2-12-10-53.8-29.2-103.6c-55.1 18.8-93.8 56.4-108.1 85.6c40.5 31.6 93.3 36.7 137.3 18zM227.8 232.6C159.6 253 93.4 252.2 87.4 252c0 .7 0 1.4 0 2.1s0 1.4 0 2.1c0 35.1 13.3 67.1 35.1 91.4c22.2-37.9 67.1-77.9 116.5-91.8c-3.4-7.8-7.2-15.5-11.1-23.2zm72.5 136.9c30.7-20.7 52.5-53.6 58.6-91.6c-4.6-1.5-42.3-12.7-85.1-5.8c17.9 49.1 25.1 89.1 26.5 97.4zm-34.8-119c45.5-5.7 90.7 3.4 95.2 4.4c-.3-32.3-11.8-61.9-30.9-85.1c-2.9 3.9-25.8 33.2-76.3 53.9c4.8 9.8 8.3 17.8 12 26.8zM384 32H64C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64zM224 416a160 160 0 1 1 0-320 160 160 0 1 1 0 320z" />
</symbol>
<symbol viewBox="0 0 448 512" id="facebook">
<path d="M64 32C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64h98.2V334.2H109.4V256h52.8V222.3c0-87.1 39.4-127.5 125-127.5c16.2 0 44.2 3.2 55.7 6.4V172c-6-.6-16.5-1-29.6-1c-42 0-58.2 15.9-58.2 57.2V256h83.6l-14.4 78.2H255V480H384c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H64z" />
</symbol>
<symbol viewBox="0 0 448 512" id="github">
<path d="M448 96c0-35.3-28.7-64-64-64H64C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V96zM265.8 407.7c0-1.8 0-6 .1-11.6c.1-11.4 .1-28.8 .1-43.7c0-15.6-5.2-25.5-11.3-30.7c37-4.1 76-9.2 76-73.1c0-18.2-6.5-27.3-17.1-39c1.7-4.3 7.4-22-1.7-45c-13.9-4.3-45.7 17.9-45.7 17.9c-13.2-3.7-27.5-5.6-41.6-5.6s-28.4 1.9-41.6 5.6c0 0-31.8-22.2-45.7-17.9c-9.1 22.9-3.5 40.6-1.7 45c-10.6 11.7-15.6 20.8-15.6 39c0 63.6 37.3 69 74.3 73.1c-4.8 4.3-9.1 11.7-10.6 22.3c-9.5 4.3-33.8 11.7-48.3-13.9c-9.1-15.8-25.5-17.1-25.5-17.1c-16.2-.2-1.1 10.2-1.1 10.2c10.8 5 18.4 24.2 18.4 24.2c9.7 29.7 56.1 19.7 56.1 19.7c0 9 .1 21.7 .1 30.6c0 4.8 .1 8.6 .1 10c0 4.3-3 9.5-11.5 8C106 393.6 59.8 330.8 59.8 257.4c0-91.8 70.2-161.5 162-161.5s166.2 69.7 166.2 161.5c.1 73.4-44.7 136.3-110.7 158.3c-8.4 1.5-11.5-3.7-11.5-8zm-90.5-54.8c-.2-1.5 1.1-2.8 3-3.2c1.9-.2 3.7 .6 3.9 1.9c.3 1.3-1 2.6-3 3c-1.9 .4-3.7-.4-3.9-1.7zm-9.1 3.2c-2.2 .2-3.7-.9-3.7-2.4c0-1.3 1.5-2.4 3.5-2.4c1.9-.2 3.7 .9 3.7 2.4c0 1.3-1.5 2.4-3.5 2.4zm-14.3-2.2c-1.9-.4-3.2-1.9-2.8-3.2s2.4-1.9 4.1-1.5c2 .6 3.3 2.1 2.8 3.4c-.4 1.3-2.4 1.9-4.1 1.3zm-12.5-7.3c-1.5-1.3-1.9-3.2-.9-4.1c.9-1.1 2.8-.9 4.3 .6c1.3 1.3 1.8 3.3 .9 4.1c-.9 1.1-2.8 .9-4.3-.6zm-8.5-10c-1.1-1.5-1.1-3.2 0-3.9c1.1-.9 2.8-.2 3.7 1.3c1.1 1.5 1.1 3.3 0 4.1c-.9 .6-2.6 0-3.7-1.5zm-6.3-8.8c-1.1-1.3-1.3-2.8-.4-3.5c.9-.9 2.4-.4 3.5 .6c1.1 1.3 1.3 2.8 .4 3.5c-.9 .9-2.4 .4-3.5-.6zm-6-6.4c-1.3-.6-1.9-1.7-1.5-2.6c.4-.6 1.5-.9 2.8-.4c1.3 .7 1.9 1.8 1.5 2.6c-.4 .9-1.7 1.1-2.8 .4z" />
</symbol>
<symbol viewBox="0 0 448 512" id="google-plus">
<path d="M448 96c0-35.3-28.7-64-64-64H64C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V96zM64 256c0-55.3 44.7-100 100-100c27 0 49.5 9.8 67 26.2l-27.1 26.1c-7.4-7.1-20.3-15.4-39.8-15.4c-34.1 0-61.9 28.2-61.9 63.2c0 34.9 27.8 63.2 61.9 63.2c39.6 0 54.4-28.5 56.8-43.1H164V241.8h94.4c1 5 1.6 10.1 1.6 16.6c0 57.1-38.3 97.6-96 97.6c-55.3 0-100-44.7-100-100zm291 18.2v29H325.8v-29h-29V245h29V216H355v29h29v29.2H355z" />
</symbol>
<symbol viewBox="0 0 1024 1024" id="heart">
<path d="M350.65 447.74c7.22-13.06 21.02-21.18 35.97-21.18l1.75 0.04c15.13 0.5 28.87 9.53 35.49 23.55l40 84.85 61.48-156.37c6.17-15.76 21.11-26 38.06-26.1 17.04 0 32 10.06 38.35 25.61l40.96 100.61 20.43-20.83c8.12-8.25 18.99-12.49 30.41-12.32 11.27 0.25 22.12 5.26 29.67 13.72l47.05 52.64h33.44c9.26-13.67 17.61-27.82 24.51-42.4 30.42-64.23 23.59-130.04-22.05-186.44-41.53-51.33-121.95-71.79-187.05-45.57-38.15 15.37-71.97 41.49-112.01 65.31-2.23-1.97-7.78-7.31-13.78-12.1-31.19-24.89-62.45-50.17-102.81-58.46-91.81-18.88-202.64 20.66-210.51 151.13-2.68 44.39 8.82 83.01 29.19 117.41h111.92l29.53-53.1z" />
<path d="M691.82 517.5l-27.12 27.65c-9.74 9.92-23.68 14.23-37.33 11.57-13.68-2.69-24.96-11.99-30.19-24.89l-33.2-81.55-60.08 152.79a41.117 41.117 0 0 1-36.97 26.08l-1.37 0.03c-16.08 0-30.34-9.06-37.2-23.63l-43.27-91.79-15.61 28.09a41.164 41.164 0 0 1-35.97 21.18h-74.56c74.41 74.49 151.59 146.23 227.63 219.09 21.93 21.02 29.11 21.07 51.4-0.32 71.87-68.95 145.17-136.51 214.65-207.78 0.22-0.22 0.43-0.45 0.64-0.67-8.83-1.67-16.99-6.11-23.08-12.9l-38.37-42.95z" />
<path d="M465.11 607.07c-7.45 0-13.99-4.14-17.19-10.93l-60.77-128.89c-0.08-0.18-0.28-0.6-0.94-0.62-0.58 0.09-0.88 0.39-0.98 0.56l-35.51 63.93c-3.36 6.04-9.74 9.8-16.65 9.8H186.22c-4.96 0-8.99-4.02-8.99-8.99 0-4.96 4.02-8.99 8.99-8.99h146.84c0.39 0 0.75-0.21 0.94-0.55l35.51-63.93c3.38-6.09 9.72-9.8 16.64-9.8 0.22 0 0.44 0 0.65 0.01 7.18 0.24 13.54 4.42 16.6 10.92l60.76 128.89c0.09 0.21 0.31 0.56 1.01 0.62 0.71-0.02 0.89-0.47 0.97-0.68l79.31-201.7c2.86-7.29 9.78-12.03 17.61-12.08h0.12c7.79 0 14.7 4.65 17.64 11.87l53.03 130.24c0.05 0.13 0.22 0.54 0.79 0.65 0.56 0.11 0.87-0.2 0.98-0.3l42.85-43.69c3.68-3.75 8.65-5.84 14.05-5.7 5.24 0.12 10.26 2.44 13.76 6.35l53.34 59.67c0.28 0.13 0.53 0.23 0.81 0.36h65.59c4.96 0 8.99 4.02 8.99 8.99 0 4.96-4.02 8.99-8.99 8.99h-65.59c-5.42 0-10.59-2.31-14.2-6.35l-53.34-59.68c-0.2-0.23-0.47-0.35-0.78-0.36-0.16 0.06-0.58 0.1-0.8 0.32l-42.84 43.69c-4.51 4.59-10.95 6.6-17.28 5.35a19.009 19.009 0 0 1-13.96-11.51L564.2 393.29c-0.09-0.24-0.35-0.69-1.01-0.67-0.73 0-0.9 0.45-0.99 0.68L482.89 595c-2.83 7.19-9.38 11.81-17.1 12.07h-0.68z" />
</symbol>
<symbol viewBox="0 0 448 512" id="instagram">
<path d="M194.4 211.7a53.3 53.3 0 1 0 59.3 88.7 53.3 53.3 0 1 0 -59.3-88.7zm142.3-68.4c-5.2-5.2-11.5-9.3-18.4-12c-18.1-7.1-57.6-6.8-83.1-6.5c-4.1 0-7.9 .1-11.2 .1c-3.3 0-7.2 0-11.4-.1c-25.5-.3-64.8-.7-82.9 6.5c-6.9 2.7-13.1 6.8-18.4 12s-9.3 11.5-12 18.4c-7.1 18.1-6.7 57.7-6.5 83.2c0 4.1 .1 7.9 .1 11.1s0 7-.1 11.1c-.2 25.5-.6 65.1 6.5 83.2c2.7 6.9 6.8 13.1 12 18.4s11.5 9.3 18.4 12c18.1 7.1 57.6 6.8 83.1 6.5c4.1 0 7.9-.1 11.2-.1c3.3 0 7.2 0 11.4 .1c25.5 .3 64.8 .7 82.9-6.5c6.9-2.7 13.1-6.8 18.4-12s9.3-11.5 12-18.4c7.2-18 6.8-57.4 6.5-83c0-4.2-.1-8.1-.1-11.4s0-7.1 .1-11.4c.3-25.5 .7-64.9-6.5-83l0 0c-2.7-6.9-6.8-13.1-12-18.4zm-67.1 44.5A82 82 0 1 1 178.4 324.2a82 82 0 1 1 91.1-136.4zm29.2-1.3c-3.1-2.1-5.6-5.1-7.1-8.6s-1.8-7.3-1.1-11.1s2.6-7.1 5.2-9.8s6.1-4.5 9.8-5.2s7.6-.4 11.1 1.1s6.5 3.9 8.6 7s3.2 6.8 3.2 10.6c0 2.5-.5 5-1.4 7.3s-2.4 4.4-4.1 6.2s-3.9 3.2-6.2 4.2s-4.8 1.5-7.3 1.5l0 0c-3.8 0-7.5-1.1-10.6-3.2zM448 96c0-35.3-28.7-64-64-64H64C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V96zM357 389c-18.7 18.7-41.4 24.6-67 25.9c-26.4 1.5-105.6 1.5-132 0c-25.6-1.3-48.3-7.2-67-25.9s-24.6-41.4-25.8-67c-1.5-26.4-1.5-105.6 0-132c1.3-25.6 7.1-48.3 25.8-67s41.5-24.6 67-25.8c26.4-1.5 105.6-1.5 132 0c25.6 1.3 48.3 7.1 67 25.8s24.6 41.4 25.8 67c1.5 26.3 1.5 105.4 0 131.9c-1.3 25.6-7.1 48.3-25.8 67z" />
</symbol>
<symbol viewBox="0 0 448 512" id="linkedin">
<path d="M416 32H31.9C14.3 32 0 46.5 0 64.3v383.4C0 465.5 14.3 480 31.9 480H416c17.6 0 32-14.5 32-32.3V64.3c0-17.8-14.4-32.3-32-32.3zM135.4 416H69V202.2h66.5V416zm-33.2-243c-21.3 0-38.5-17.3-38.5-38.5S80.9 96 102.2 96c21.2 0 38.5 17.3 38.5 38.5 0 21.3-17.2 38.5-38.5 38.5zm282.1 243h-66.4V312c0-24.8-.5-56.7-34.5-56.7-34.6 0-39.9 27-39.9 54.9V416h-66.4V202.2h63.7v29.2h.9c8.9-16.8 30.6-34.5 62.9-34.5 67.2 0 79.7 44.3 79.7 101.9V416z" />
</symbol>
<symbol viewBox="0 0 640 512" id="medium">
<path d="M180.5 74.3C80.8 74.3 0 155.6 0 256S80.8 437.7 180.5 437.7 361 356.4 361 256 280.2 74.3 180.5 74.3zm288.3 10.6c-49.8 0-90.2 76.6-90.2 171.1s40.4 171.1 90.3 171.1 90.3-76.6 90.3-171.1H559C559 161.5 518.6 84.9 468.8 84.9zm139.5 17.8c-17.5 0-31.7 68.6-31.7 153.3s14.2 153.3 31.7 153.3S640 340.6 640 256C640 171.4 625.8 102.7 608.3 102.7z" />
</symbol>
<symbol viewBox="0 0 496 512" id="pinterest">
<path d="M496 256c0 137-111 248-248 248-25.6 0-50.2-3.9-73.4-11.1 10.1-16.5 25.2-43.5 30.8-65 3-11.6 15.4-59 15.4-59 8.1 15.4 31.7 28.5 56.8 28.5 74.8 0 128.7-68.8 128.7-154.3 0-81.9-66.9-143.2-152.9-143.2-107 0-163.9 71.8-163.9 150.1 0 36.4 19.4 81.7 50.3 96.1 4.7 2.2 7.2 1.2 8.3-3.3 .8-3.4 5-20.3 6.9-28.1 .6-2.5 .3-4.7-1.7-7.1-10.1-12.5-18.3-35.3-18.3-56.6 0-54.7 41.4-107.6 112-107.6 60.9 0 103.6 41.5 103.6 100.9 0 67.1-33.9 113.6-78 113.6-24.3 0-42.6-20.1-36.7-44.8 7-29.5 20.5-61.3 20.5-82.6 0-19-10.2-34.9-31.4-34.9-24.9 0-44.9 25.7-44.9 60.2 0 22 7.4 36.8 7.4 36.8s-24.5 103.8-29 123.2c-5 21.4-3 51.6-.9 71.2C65.4 450.9 0 361.1 0 256 0 119 111 8 248 8s248 111 248 248z" />
</symbol>
<symbol viewBox="0 0 448 512" id="qq">
<path d="M433.8 420.4c-11.5 1.4-44.9-52.7-44.9-52.7 0 31.3-16.1 72.2-51.1 101.8 16.8 5.2 54.8 19.2 45.8 34.4-7.3 12.3-125.5 7.9-159.6 4-34.1 3.8-152.3 8.3-159.6-4-9-15.3 28.9-29.2 45.8-34.4-34.9-29.5-51.1-70.4-51.1-101.8 0 0-33.3 54.1-44.9 52.7-5.4-.7-12.4-29.6 9.3-99.7 10.3-33 22-60.5 40.1-105.8C60.7 98.1 109 0 224 0c113.7 0 163.2 96.1 160.3 215 18.1 45.2 29.9 72.9 40.1 105.8 21.8 70.1 14.7 99.1 9.3 99.7z" />
</symbol>
<symbol viewBox="0 0 512 512" id="reddit">
<path d="M0 256C0 114.6 114.6 0 256 0S512 114.6 512 256s-114.6 256-256 256L37.1 512c-13.7 0-20.5-16.5-10.9-26.2L75 437C28.7 390.7 0 326.7 0 256zM349.6 153.6c23.6 0 42.7-19.1 42.7-42.7s-19.1-42.7-42.7-42.7c-20.6 0-37.8 14.6-41.8 34c-34.5 3.7-61.4 33-61.4 68.4l0 .2c-37.5 1.6-71.8 12.3-99 29.1c-10.1-7.8-22.8-12.5-36.5-12.5c-33 0-59.8 26.8-59.8 59.8c0 24 14.1 44.6 34.4 54.1c2 69.4 77.6 125.2 170.6 125.2s168.7-55.9 170.6-125.3c20.2-9.6 34.1-30.2 34.1-54c0-33-26.8-59.8-59.8-59.8c-13.7 0-26.3 4.6-36.4 12.4c-27.4-17-62.1-27.7-100-29.1l0-.2c0-25.4 18.9-46.5 43.4-49.9l0 0c4.4 18.8 21.3 32.8 41.5 32.8zM177.1 246.9c16.7 0 29.5 17.6 28.5 39.3s-13.5 29.6-30.3 29.6s-31.4-8.8-30.4-30.5s15.4-38.3 32.1-38.3zm190.1 38.3c1 21.7-13.7 30.5-30.4 30.5s-29.3-7.9-30.3-29.6c-1-21.7 11.8-39.3 28.5-39.3s31.2 16.6 32.1 38.3zm-48.1 56.7c-10.3 24.6-34.6 41.9-63 41.9s-52.7-17.3-63-41.9c-1.2-2.9 .8-6.2 3.9-6.5c18.4-1.9 38.3-2.9 59.1-2.9s40.7 1 59.1 2.9c3.1 .3 5.1 3.6 3.9 6.5z" />
</symbol>
<symbol viewBox="0 0 496 512" id="telegram">
<path d="M248 8C111 8 0 119 0 256S111 504 248 504 496 393 496 256 385 8 248 8zM363 176.7c-3.7 39.2-19.9 134.4-28.1 178.3-3.5 18.6-10.3 24.8-16.9 25.4-14.4 1.3-25.3-9.5-39.3-18.7-21.8-14.3-34.2-23.2-55.3-37.2-24.5-16.1-8.6-25 5.3-39.5 3.7-3.8 67.1-61.5 68.3-66.7 .2-.7 .3-3.1-1.2-4.4s-3.6-.8-5.1-.5q-3.3 .7-104.6 69.1-14.8 10.2-26.9 9.9c-8.9-.2-25.9-5-38.6-9.1-15.5-5-27.9-7.7-26.8-16.3q.8-6.7 18.5-13.7 108.4-47.2 144.6-62.3c68.9-28.6 83.2-33.6 92.5-33.8 2.1 0 6.6 .5 9.6 2.9a10.5 10.5 0 0 1 3.5 6.7A43.8 43.8 0 0 1 363 176.7z" />
</symbol>
<symbol viewBox="0 0 448 512" id="tiktok">
<path d="M448 209.9a210.1 210.1 0 0 1 -122.8-39.3V349.4A162.6 162.6 0 1 1 185 188.3V278.2a74.6 74.6 0 1 0 52.2 71.2V0l88 0a121.2 121.2 0 0 0 1.9 22.2h0A122.2 122.2 0 0 0 381 102.4a121.4 121.4 0 0 0 67 20.1z" />
</symbol>
<symbol viewBox="0 0 448 512" id="tumblr">
<path d="M448 96c0-35.3-28.7-64-64-64H64C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V96zM256.8 416c-75.5 0-91.9-55.5-91.9-87.9v-90H135.2c-3.4 0-6.2-2.8-6.2-6.2V189.4c0-4.5 2.8-8.5 7.1-10c38.8-13.7 50.9-47.5 52.7-73.2c.5-6.9 4.1-10.2 10-10.2h44.3c3.4 0 6.2 2.8 6.2 6.2v72h51.9c3.4 0 6.2 2.8 6.2 6.2v51.1c0 3.4-2.8 6.2-6.2 6.2H249.1V321c0 21.4 14.8 33.5 42.5 22.4c3-1.2 5.6-2 8-1.4c2.2 .5 3.6 2.1 4.6 4.9L318 387.1c1 3.2 2 6.7-.3 9.1c-8.5 9.1-31.2 19.8-60.9 19.8z" />
</symbol>
<symbol viewBox="0 0 512 512" id="twitter">
<path d="M459.4 151.7c.3 4.5 .3 9.1 .3 13.6 0 138.7-105.6 298.6-298.6 298.6-59.5 0-114.7-17.2-161.1-47.1 8.4 1 16.6 1.3 25.3 1.3 49.1 0 94.2-16.6 130.3-44.8-46.1-1-84.8-31.2-98.1-72.8 6.5 1 13 1.6 19.8 1.6 9.4 0 18.8-1.3 27.6-3.6-48.1-9.7-84.1-52-84.1-103v-1.3c14 7.8 30.2 12.7 47.4 13.3-28.3-18.8-46.8-51-46.8-87.4 0-19.5 5.2-37.4 14.3-53 51.7 63.7 129.3 105.3 216.4 109.8-1.6-7.8-2.6-15.9-2.6-24 0-57.8 46.8-104.9 104.9-104.9 30.2 0 57.5 12.7 76.7 33.1 23.7-4.5 46.5-13.3 66.6-25.3-7.8 24.4-24.4 44.8-46.1 57.8 21.1-2.3 41.6-8.1 60.4-16.2-14.3 20.8-32.2 39.3-52.6 54.3z" />
</symbol>
<symbol viewBox="0 0 448 512" id="vimeo">
<path d="M403.2 32H44.8C20.1 32 0 52.1 0 76.8v358.4C0 459.9 20.1 480 44.8 480h358.4c24.7 0 44.8-20.1 44.8-44.8V76.8c0-24.7-20.1-44.8-44.8-44.8zM377 180.8c-1.4 31.5-23.4 74.7-66 129.4-44 57.2-81.3 85.8-111.7 85.8-18.9 0-34.8-17.4-47.9-52.3-25.5-93.3-36.4-148-57.4-148-2.4 0-10.9 5.1-25.4 15.2l-15.2-19.6c37.3-32.8 72.9-69.2 95.2-71.2 25.2-2.4 40.7 14.8 46.5 51.7 20.7 131.2 29.9 151 67.6 91.6 13.5-21.4 20.8-37.7 21.8-48.9 3.5-33.2-25.9-30.9-45.8-22.4 15.9-52.1 46.3-77.4 91.2-76 33.3 .9 49 22.5 47.1 64.7z" />
</symbol>
<symbol viewBox="0 0 512 512" id="weibo">
<path d="M407 177.6c7.6-24-13.4-46.8-37.4-41.7-22 4.8-28.8-28.1-7.1-32.8 50.1-10.9 92.3 37.1 76.5 84.8-6.8 21.2-38.8 10.8-32-10.3zM214.8 446.7C108.5 446.7 0 395.3 0 310.4c0-44.3 28-95.4 76.3-143.7C176 67 279.5 65.8 249.9 161c-4 13.1 12.3 5.7 12.3 6 79.5-33.6 140.5-16.8 114 51.4-3.7 9.4 1.1 10.9 8.3 13.1 135.7 42.3 34.8 215.2-169.7 215.2zm143.7-146.3c-5.4-55.7-78.5-94-163.4-85.7-84.8 8.6-148.8 60.3-143.4 116s78.5 94 163.4 85.7c84.8-8.6 148.8-60.3 143.4-116zM347.9 35.1c-25.9 5.6-16.8 43.7 8.3 38.3 72.3-15.2 134.8 52.8 111.7 124-7.4 24.2 29.1 37 37.4 12 31.9-99.8-55.1-195.9-157.4-174.3zm-78.5 311c-17.1 38.8-66.8 60-109.1 46.3-40.8-13.1-58-53.4-40.3-89.7 17.7-35.4 63.1-55.4 103.4-45.1 42 10.8 63.1 50.2 46 88.5zm-86.3-30c-12.9-5.4-30 .3-38 12.9-8.3 12.9-4.3 28 8.6 34 13.1 6 30.8 .3 39.1-12.9 8-13.1 3.7-28.3-9.7-34zm32.6-13.4c-5.1-1.7-11.4 .6-14.3 5.4-2.9 5.1-1.4 10.6 3.7 12.9 5.1 2 11.7-.3 14.6-5.4 2.8-5.2 1.1-10.9-4-12.9z" />
</symbol>
<symbol viewBox="0 0 576 512" id="weixin">
<path d="M385.2 167.6c6.4 0 12.6 .3 18.8 1.1C387.4 90.3 303.3 32 207.7 32 100.5 32 13 104.8 13 197.4c0 53.4 29.3 97.5 77.9 131.6l-19.3 58.6 68-34.1c24.4 4.8 43.8 9.7 68.2 9.7 6.2 0 12.1-.3 18.3-.8-4-12.9-6.2-26.6-6.2-40.8-.1-84.9 72.9-154 165.3-154zm-104.5-52.9c14.5 0 24.2 9.7 24.2 24.4 0 14.5-9.7 24.2-24.2 24.2-14.8 0-29.3-9.7-29.3-24.2 .1-14.7 14.6-24.4 29.3-24.4zm-136.4 48.6c-14.5 0-29.3-9.7-29.3-24.2 0-14.8 14.8-24.4 29.3-24.4 14.8 0 24.4 9.7 24.4 24.4 0 14.6-9.6 24.2-24.4 24.2zM563 319.4c0-77.9-77.9-141.3-165.4-141.3-92.7 0-165.4 63.4-165.4 141.3S305 460.7 397.6 460.7c19.3 0 38.9-5.1 58.6-9.9l53.4 29.3-14.8-48.6C534 402.1 563 363.2 563 319.4zm-219.1-24.5c-9.7 0-19.3-9.7-19.3-19.6 0-9.7 9.7-19.3 19.3-19.3 14.8 0 24.4 9.7 24.4 19.3 0 10-9.7 19.6-24.4 19.6zm107.1 0c-9.7 0-19.3-9.7-19.3-19.6 0-9.7 9.7-19.3 19.3-19.3 14.5 0 24.4 9.7 24.4 19.3 .1 10-9.9 19.6-24.4 19.6z" />
</symbol>
<symbol viewBox="0 0 448 512" id="x-twitter">
<path d="M64 32C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H64zm297.1 84L257.3 234.6 379.4 396H283.8L209 298.1 123.3 396H75.8l111-126.9L69.7 116h98l67.7 89.5L313.6 116h47.5zM323.3 367.6L153.4 142.9H125.1L296.9 367.6h26.3z" />
</symbol>
<symbol viewBox="0 0 576 512" id="youtube">
<path d="M549.7 124.1c-6.3-23.7-24.8-42.3-48.3-48.6C458.8 64 288 64 288 64S117.2 64 74.6 75.5c-23.5 6.3-42 24.9-48.3 48.6-11.4 42.9-11.4 132.3-11.4 132.3s0 89.4 11.4 132.3c6.3 23.7 24.8 41.5 48.3 47.8C117.2 448 288 448 288 448s170.8 0 213.4-11.5c23.5-6.3 42-24.2 48.3-47.8 11.4-42.9 11.4-132.3 11.4-132.3s0-89.4-11.4-132.3zm-317.5 213.5V175.2l142.7 81.2-142.7 81.2z" />
</symbol>
<symbol viewBox="0 0 640 512" id="zhihu">
<path d="M170.5 148.1v217.5l23.4 0 7.7 26.4 42-26.4h49.5V148.1H170.5zm97.8 193.9h-27.9l-27.9 17.5-5.1-17.5-11.9 0V171.8h72.8v170.3zm-118.5-94.4H97.5c1.7-27.1 2.2-51.6 2.2-73.5h51.2s2-22.6-8.6-22.3h-88.5c3.5-13.1 7.9-26.7 13.1-40.7 0 0-24.1 0-32.3 21.6-3.4 8.9-13.2 43.1-30.7 78.1 5.9-.6 25.4-1.2 36.8-22.2 2.1-5.9 2.5-6.7 5.1-14.5h28.9c0 10.5-1.2 66.9-1.7 73.4H20.8c-11.7 0-15.6 23.6-15.6 23.6h65.6C66.5 321.1 42.8 363.1 0 396.3c20.5 5.9 40.9-.9 51-9.9 0 0 23-20.9 35.6-69.3l54 64.9s7.9-26.9-1.2-40c-7.6-8.9-28.1-33.1-36.8-41.8L87.9 312c4.4-14 7-27.6 7.9-40.7h61.7s-.1-23.6-7.6-23.6v0zm412-1.6c20.8-25.6 45-58.6 45-58.6s-18.7-14.8-27.4-4.1c-6 8.2-36.8 48.2-36.8 48.2l19.2 14.4zm-150.1-59.1c-9-8.3-25.9 2.1-25.9 2.1s39.5 55 41.1 57.5l19.5-13.7s-25.7-37.6-34.7-45.9h0zM640 258.4c-19.8 0-130.9 .9-131.1 .9v-101c4.8 0 12.4-.4 22.9-1.2 40.9-2.4 70.1-4 87.8-4.8 0 0 12.2-27.2-.6-33.4-3.1-1.2-23.2 4.6-23.2 4.6s-165.2 16.5-232.4 18.1c1.6 8.8 7.6 17.1 15.8 19.6 13.3 3.5 22.7 1.7 49.2 .9 24.8-1.6 43.7-2.4 56.5-2.4v99.8H351.4s2.8 22.3 25.5 22.9h107.9v70.9c0 14-11.2 22-24.5 21.1-14.1 .1-26.1-1.2-41.7-1.8 2 4 6.3 14.4 19.3 21.8 9.9 4.8 16.2 6.6 26 6.6 29.6 0 45.7-17.3 44.9-45.3v-73.3h122.4c9.7 0 8.7-23.8 8.7-23.8l0 0z" />
</symbol>
</svg>
</body>
</html>在我们继续之前,我想解释一下上面代码片段中的 class="sr-only" 。通过 CSS 为 .sr-only 定义一段样式来隐藏 SVG。
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border-width: 0;
}虽然说,<symbol> 不会在 SVG 画布上呈现任何内容,但 <svg> 仍然会占用页面上的空间(将 <svg> 嵌套在 HTML 文档中),导致出现一个大的空白区域,有可能会打破你的 Web 布局。为了避免这种情况,我们通过 .sr-only 中的样式隐藏 SVG,使其在页面上不占任何空间。需要知道的是,这样做并不会影响 SVG 雪碧图的使用效果。
一旦你准备好了 SVG 雪碧图,你就可以通过使用 SVG 的 <use> 元素引用它们,在页面上的任何地方显示图标:
<svg class="icon">
<use href="#dribbble" />
</svg>就是这样!
我们也可以将 SVG 雪碧图保存为单独的 .svg 。例如 icons.svg ,在这个文件中,同样使用 <symbol> 实例化 SVG 图标:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<symbol viewBox="0 0 448 512" id="dribbble">
<path d="M165.9 132.5c-38.3 18-66.8 53.3-75.7 95.7c6.1 .1 62.4 .3 126.4-16.7c-22.7-40.2-47.1-74.1-50.7-79zm26.1-9.1c3.8 5.1 28.6 38.9 51 80c48.6-18.3 69.1-45.9 71.6-49.4C281 124.2 235.3 112.9 192 123.4zM277.4 382c-2-12-10-53.8-29.2-103.6c-55.1 18.8-93.8 56.4-108.1 85.6c40.5 31.6 93.3 36.7 137.3 18zM227.8 232.6C159.6 253 93.4 252.2 87.4 252c0 .7 0 1.4 0 2.1s0 1.4 0 2.1c0 35.1 13.3 67.1 35.1 91.4c22.2-37.9 67.1-77.9 116.5-91.8c-3.4-7.8-7.2-15.5-11.1-23.2zm72.5 136.9c30.7-20.7 52.5-53.6 58.6-91.6c-4.6-1.5-42.3-12.7-85.1-5.8c17.9 49.1 25.1 89.1 26.5 97.4zm-34.8-119c45.5-5.7 90.7 3.4 95.2 4.4c-.3-32.3-11.8-61.9-30.9-85.1c-2.9 3.9-25.8 33.2-76.3 53.9c4.8 9.8 8.3 17.8 12 26.8zM384 32H64C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64zM224 416a160 160 0 1 1 0-320 160 160 0 1 1 0 320z" />
</symbol>
<symbol viewBox="0 0 448 512" id="facebook">
<path d="M64 32C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64h98.2V334.2H109.4V256h52.8V222.3c0-87.1 39.4-127.5 125-127.5c16.2 0 44.2 3.2 55.7 6.4V172c-6-.6-16.5-1-29.6-1c-42 0-58.2 15.9-58.2 57.2V256h83.6l-14.4 78.2H255V480H384c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H64z" />
</symbol>
<!-- 省略其他的 SVG 图标 -->
</svg> 我们把这种方式称为外部 SVG 雪碧图。与内联 SVG 雪碧图不一样的是,在 HTML 中引用外部 SVG 雪碧图中的图标,需要利用 SVG 片段标识符在雪碧图中选择单个图标。例如:
<svg class="icon">
<use href="icons.svg#dribbble" />
</svg>
<svg class="icon">
<use href="icons.svg#facebook" />
</svg> 上面示例中的 icons.svg 是包含所有图标的 SVG 文件的名称(也称外部 SVG 雪碧图),而片段标识符 #dribbble 和 #facebook 分别对应的是 icons.svg 文件中 id 为 dribbble 和 facebook 的 <symbol> 。
如果硬编码的方式创建 SVG 雪碧图令你感到厌烦的话,那么你可以考虑使用工具来帮助你快速创建 SVG 雪碧图。例如 svgsprit.es 可以帮助你快速构建 SVG 雪碧图:
虽然这种方式可以帮助你快速获得 SVG 雪碧图,但我们要构建的是 SVG 图标系统,该系统必须具备非规定性、可扩展性。换句话说,我们更希望以自动化的方式来创建 SVG 雪碧图,即它能将 icons 目录下的 SVG 图标生成 SVG 雪碧图。
庆幸的是,有一些工具可以自动化创建 SVG 雪碧图。@Joschi Kuphal 制作了一个很棒的工具 SVG Sprite,他还将其移植到了 Gulp 中,称为 gulp-svg-sprite。SVG Sprite 工具非常棒。它提供了多种 SVG 雪碧图的选项,例如:
background-image)<view> 元素的 CSS 雪碧图,适应于背景图(background-image),也适应用于 HTML 的 <img><defs> 元素创建的内联 SVG 雪碧图<symbol> 元素创建的内联 SVG 雪碧图除此之外,还有一些额外的好处,比如为你构建一个参考页。这个参考页相当于 SVG 雪碧图的集成到 Web 应用或网站的使用指南。
假设你为 SVG 图标系统创建了一个名为 svg 的项目,在该项目的根目录下创建一个 icons 文件夹,并把单个 SVG 图标文件放置在 icons 文件夹中。接下来,你就可以通过 SVG Sprite 工具来自动创建 SVG 雪碧图。首先在该项目根目录下创建一个 gulpfile.js 文件,根据 SVG Sprite 工具的使用文档,在 gulpfile.js 文件中配置生成 SVG 雪碧图所需的选项。
'use-strict';
const { src, dest, series } = require('gulp');
const svgSprite = require('gulp-svg-sprite');
// 配置参数
const config = {
mode: {
// css: true, // 传统的 CSS 雪碧图,用于背景图像(background-image)
// view: true, // 带有预定义的 <view> 元素的 CSS 雪碧图
// defs: true, // 使用 <defs> 元素创建的内联 SVG 雪碧图
// stack: true, // SVG 堆栈雪碧图
symbol: { // 使用 <symbol> 元素创建的内联 SVG 雪碧图
dest: 'sprite', // 放置生成的 SVG 雪碧图文件夹
sprite: 'sprite.svg', // SVG 雪碧图文件名
example: true // 生成参考页,使用指南
}
},
svg: {
xmlDeclaration: false, // 移除 XML 属性
doctypeDeclaration: false // 不包括 DOCTYPE 声明
}
};
function spritePage() {
return src('icons/**/*.svg') // 放置 SVG 图标文件的路径
.pipe(svgSprite(config))
.pipe(dest('.'));
}
function spriteShortcut() {
return src('sprite/sprite.svg') // 生成 SVG 雪碧图
.pipe(dest('.'));
}
exports.default = series(spritePage, spriteShortcut);配置完 gulpfile.js 之后,你需要在 package.json 文件中配置依赖包和执行脚本:
{
"name": "svg",
"main": "index.js",
"scripts": {
"gulp": "gulp",
"test": "echo \"Error: no test specified\" && exit 1"
},
"devDependencies": {
"gulp": "^5.0.0",
"gulp-rename": "^2.0.0",
"gulp-svg-sprite": "^2.0.3"
}
}安装完所需的依赖包之后,在命令终端执行 gulp 命令,就能根据 icons 目录下的 SVG 图标自动生成你所需要的 SVG 雪碧图:
在项目的 sprite 目录下,你可以找到生成后的 sprite.svg 文件:
在这个目录下还为你生成了一个参考页:
接下来,你就可以在项目中通过 <use> 元素以外联 SVG 雪碧图的方式引用所需的 SVG 图标:
<svg class="icon icon--twitter">
<use href="sprite.svg#twitter" />
</svg>
<svg class="icon icon--github">
<use href="sprite.svg#github" />
</svg>
<svg class="icon icon--qq">
<use href="sprite.svg#qq" />
</svg>现在,你可以随时往 icons 文件夹中添加 SVG 图标文件。SVG Sprite 的另一个优势是它尊重命名图标的文件夹系统。这意味着,如果我们的基础文件夹是 icons/ ,那么该文件夹中的任何内容都可以通过其名称(SVG 图标文件名)进行引用,而文件夹中的任何内容都将被添加前缀:
icons/
|-- twitter.svg // sprite.svg#twitter
|-- github.svg // sprite.svg#github
|
|--weather/
|--bolt.svg // sprite.svg#weather--bolt
|--cloud.svg // sprite.svg#weather--cloud
|
|--animals
|--feather.svg // sprite.svg#animals--feather
|--hippo.svg // sprite.svg#animals--hippo在考虑这种命名结构时,你现在可以教会你的设计师如何将图标添加到该文件夹并提交拉取请求!效率大大提高!添加新图标时,它们不会影响现有图标,而是增加系统的图标选项:
<!-- 位于 icons 目录下的 SVG 图标 -->
<svg class="icon icon--twitter">
<use href="sprite.svg#twitter" />
</svg>
<svg class="icon icon--github">
<use href="sprite.svg#github" />
</svg>
<!-- 位于 icons/animals 目录下的 SVG 图标 -->
<svg class="icon icon--feather">
<use href="sprite.svg#animals--feather" />
</svg>
<svg class="icon icon--hippo">
<use href="sprite.svg#animals--hippo" />
</svg>
<!-- 位于 icons/weather 目录下的 SVG 图标 -->
<svg class="icon icon--umbrella">
<use href="sprite.svg#weather--umbrella" />
</svg>
<svg class="icon icon--snowflake">
<use href="sprite.svg#weather--snowflake" />
</svg>具备了自动化生成 SVG 雪碧图能力之后,你不用再担心有新的 SVG 图标加入了。
注意,在这里我们仅演示了 SVG Sprite 工具中的 gulp-svg-sprite 是如何自动生成 SVG 雪碧图的。类似这样的工具和工程能力还有很多,比如 Webpack、Vite 等,它们可以帮助你快速生成 SVG 雪碧图。在后续的实战课程中还将涉及这方面的内容。这里就不做更多的阐述。
生成的 SVG 雪碧图,我们有多种方式可以将其引用到 Web 应用或网站,常见的方式分为内联和外联 SVG 雪碧图。其中内联的方式指的是将生成的 SVG 雪碧图文件(sprite.svg)对应的 SVG 代码,直接复制粘贴到你的 HTML 文档中,例如:
<body>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" class="sr-only">
<symbol viewBox="0 0 512 512" id="animals--feather">
<path d="M278.5 215.6 23 471c-9.4 9.4-9.4 24.6 0 33.9s24.6 9.4 33.9 0l57-57h68c49.7 0 97.9-14.4 139-41 11.1-7.2 5.5-23-7.8-23-5.1 0-9.2-4.1-9.2-9.2 0-4.1 2.7-7.6 6.5-8.8l81-24.3c2.5-.8 4.8-2.1 6.7-4l22.4-22.4c10.1-10.1 2.9-27.3-11.3-27.3H377c-5.1 0-9.2-4.1-9.2-9.2 0-4.1 2.7-7.6 6.5-8.8l112-33.6c4-1.2 7.4-3.9 9.3-7.7 10.8-21 16.4-44.5 16.4-68.6 0-41-16.3-80.3-45.3-109.3l-5.5-5.5C432.3 16.3 393 0 352 0s-80.3 16.3-109.3 45.3L139 149c-48 48-75 113.1-75 181v55.3l189.6-189.5c6.2-6.2 16.4-6.2 22.6 0 5.4 5.4 6.1 13.6 2.2 19.8z"/>
</symbol>
<!-- 省略其他 symbol -->
</svg>
</body>此时,你在 HTML 文档中,可以直接使用 <use> 来引用所需的 SVG 图标:
<svg class="icon icon--feather">
<use href="#animals--feather" />
</svg>外联 SVG 雪碧图的使用方式与内联 SVG 雪碧图方式有点相似,唯一不同的是,SVG 雪碧图是以文件引入的方式加载到 Web 应用或网站的。
<svg class="icon icon--twitter">
<use href="sprite.svg#twitter" />
</svg>看上去是不是与 <img> 为 Web 添加图片的方式相似。
如果你采用的是外联 SVG 雪碧图的方式,那么建议你对 sprite.svg 做一个预加载的处理。你可以使用 <link> 标签的 preload 功能,将 sprite.svg 文件添加到 <head> 中:
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="preload" href="sprite.svg" />
</head>
<body>
<svg class="icon icon--twitter">
<use href="sprite.svg#twitter" />
</svg>
</body>
</html> 这是在性能优化上的一个小细节,过多就不在这里阐述了。这里不对两种使用方式做对比,仅从我个人喜好出发,我自己更喜欢使用内联 SVG 雪碧图的方式。
在实际应用的时候,我们还可以考虑 SVG 图标可访问性,它不会额外为你增加太多工作量,但对于你的应用有较多的好处,比如,使每一位访问你的应用的用户都有平等、统一的体验。
<button type="button">
<svg role="img" class="icon icon--twitter" aria-labelledby="button-title" focusable="false">
<title id="button-title">Twitter</title>
<use href="#twitter" />
</svg>
</button>
<a href="#">
<svg role="img" class="icon icon--twitter" aria-labelledby="link-title" focusable="false">
<title id="link-title">Jump to Twitter</title>
<use xlink:href="#twitter" />
</svg>
</a>
<button type="button">
<svg class="icon icon--twitter" aria-hidden="true" focusable="false">
<use xlink:href="#twitter" />
</svg>
Twitter
</button>
<a href="#">
Jump to Twitter
<svg class="icon icon--twitter" aria-hidden="true" focusable="false">
<use xlink:href="#twitter" />
</svg>
</a>上面代码所展示的几种方式,都是使 SVG 图标在被应用时更具可访问性,易于辅助技术(例如屏幕阅读器)识别。
也有一些人建议在创建 SVG 雪碧图时,在每个 <symbol> 中放置一个 <title> 元素,对 SVG 图标进行描述。但我不建议这么做,因为我认为这是一个错误的做法。以“放大镜”这个图标为例,当它放在不同的上下文中时,所代表的含义就有可能不同。它有可能是“显示搜索结果”,也有可能是“提交搜索查询”。因此,你的文本标签应该是“显示搜索结果”和“提交搜索查询”,而不是“搜索”(太通用了),千万别写“放大镜图标”,这是非常不好的做法(仅描述了图标的视觉效果,并没有表达图标在上下文中的含义)。这意味着,如果你在 <symbol> 中使用 <title> 对“放大镜”图标进行任何描述,它都很难与上下文所表达的意思相匹配。
非常不幸的是,以 <symbol> 方式创建的 SVG 雪碧图不能用于 HTML 的 <img> 元素,也不能用于 CSS 的 background-image 。但可以以传统的 CSS 雪碧图的方式来使用 SVG 雪碧图。换句话说,我们依旧可以将所有 SVG 图标拼接在一起,并以 SVG 雪碧图的方式存在,然后将其应用于 CSS 的 background-image 。
继续以 SVG Sprite 工具为例,它就提供了 css 模式,将 icons 目录下的所有 SVG 图标自动生成一张 SVG 雪碧图,它不是以 <symbol> 方式实例化的,而是以 <svg> 方式存在的。你只需在 gulpfile.js 配置文件中开启 css 模式的配置:
const config = {
mode: {
css:{
render: {
css: true
},
dest: 'sprite',
sprite: 'sprite.svg',
example: true
},
}
};生成的 SVG 雪碧图如下:
<svg width="3328" height="2560" viewBox="0 0 3328 2560" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<svg viewBox="0 0 512 512" width="512" height="512" id="animals--feather" x="1152" y="1024" xmlns="http://www.w3.org/2000/svg">
<path d="M278.5 215.6 23 471c-9.4 9.4-9.4 24.6 0 33.9s24.6 9.4 33.9 0l57-57h68c49.7 0 97.9-14.4 139-41 11.1-7.2 5.5-23-7.8-23-5.1 0-9.2-4.1-9.2-9.2 0-4.1 2.7-7.6 6.5-8.8l81-24.3c2.5-.8 4.8-2.1 6.7-4l22.4-22.4c10.1-10.1 2.9-27.3-11.3-27.3H377c-5.1 0-9.2-4.1-9.2-9.2 0-4.1 2.7-7.6 6.5-8.8l112-33.6c4-1.2 7.4-3.9 9.3-7.7 10.8-21 16.4-44.5 16.4-68.6 0-41-16.3-80.3-45.3-109.3l-5.5-5.5C432.3 16.3 393 0 352 0s-80.3 16.3-109.3 45.3L139 149c-48 48-75 113.1-75 181v55.3l189.6-189.5c6.2-6.2 16.4-6.2 22.6 0 5.4 5.4 6.1 13.6 2.2 19.8z"/>
</svg>
<!-- 省略其他 SVG 图标 -->
</svg>然后,你就可以在 CSS 中像下面这样引用 SVG 图标:
<div class="icon--feather"></div>.icon--feather {
display: block;
background: url("sprite.svg") 40.90909090909091% 50% no-repeat;
background-size: 3328px 2560px !important;
width: 512px;
height: 512px;
}你甚至还可以使用 eeencode 工具,将生成的 sprite.svg (雪碧图)文件转换成 Data URI,并在 CSS 中引用指定的 SVG 图标:
<div class="icon--twitter"></div>:root {
--sprite: url("data:image/svg+xml;base64,PHN2...");
}
.icon--twitter {
background: var(--sprite) 35.79545454545455% 100% no-repeat;
background-size: 3328px 2560px !important;
width: 512px;
height: 512px;
}在这种情况下,SVG 雪碧图实际上是一张图片,而不是一个 SVG 容器,图标的使用方式与 CSS 雪碧图非常相似,图标作为背景图像提供。这种技术最大的缺点是,以背景图像嵌入的 SVG 无法使用 CSS 进行样式化。另外就是,每个图标的定位(background-position)和适配性都没有内联和外联 SVG 雪碧图那样灵活。
除了上面所提到的使用方式之外,我们还可以使用 SVG 的堆叠和视图的技术。首先来看 SVG 堆叠的技术,它将 icons 目录下所有 SVG 图标叠在一起,并且默认所有 SVG 雪碧图中所有图标都不可见,只有被 SVG 片段标识符选中的图标才可见。
同样可以使用 SVG Sprite 工具,将 icons 文件夹下所有图标堆叠在一起:
// gulpfile.js
const config = {
mode: {
stack: {
dest: 'sprite',
sprite: 'sprite.svg',
example: true
}
}
};生成的 sprite.svg 代码如下:
<svg viewBox="0 0 640 512" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<style>
:root > svg{
display:none
}
:root > svg:target{
display:block
}
</style>
<svg viewBox="0 0 512 512" id="animals--feather" xmlns="http://www.w3.org/2000/svg">
<path d="M278.5 215.6 23 471c-9.4 9.4-9.4 24.6 0 33.9s24.6 9.4 33.9 0l57-57h68c49.7 0 97.9-14.4 139-41 11.1-7.2 5.5-23-7.8-23-5.1 0-9.2-4.1-9.2-9.2 0-4.1 2.7-7.6 6.5-8.8l81-24.3c2.5-.8 4.8-2.1 6.7-4l22.4-22.4c10.1-10.1 2.9-27.3-11.3-27.3H377c-5.1 0-9.2-4.1-9.2-9.2 0-4.1 2.7-7.6 6.5-8.8l112-33.6c4-1.2 7.4-3.9 9.3-7.7 10.8-21 16.4-44.5 16.4-68.6 0-41-16.3-80.3-45.3-109.3l-5.5-5.5C432.3 16.3 393 0 352 0s-80.3 16.3-109.3 45.3L139 149c-48 48-75 113.1-75 181v55.3l189.6-189.5c6.2-6.2 16.4-6.2 22.6 0 5.4 5.4 6.1 13.6 2.2 19.8z"/>
</svg>
<svg viewBox="0 0 640 512" id="animals--hippo" xmlns="http://www.w3.org/2000/svg">
<path d="M407 47c9.4-9.4 24.6-9.4 33.9 0l17.2 17.2c1.9-.1 3.9-.2 5.8-.2h32c11.2 0 21.9 2.3 31.6 6.5L543 55c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9l-12.9 13c7.6 12.2 12 26.7 12 42.1 0 10.2 7.4 18.8 16.7 23 27.9 12.5 47.3 40.5 47.3 73 0 26.2-12.6 49.4-32 64v32c0 8.8-7.2 16-16 16h-32c-8.8 0-16-7.2-16-16v-16h-64v16c0 8.8-7.2 16-16 16h-32c-8.8 0-16-7.2-16-16v-17.6c-11.8-2.4-22.7-7.4-32-14.4-1.5-1.1-2.9-2.3-4.3-3.5-17-14.7-27.7-36.4-27.7-60.5 0-8.8-7.2-16-16-16s-16 7.2-16 16c0 44.7 26.2 83.2 64 101.2V352c0 17.7 14.3 32 32 32h32v64c0 17.7-14.3 32-32 32h-64c-17.7 0-32-14.3-32-32v-76c-19.8 7.7-41.4 12-64 12s-44.2-4.3-64-12v76c0 17.7-14.3 32-32 32H96c-17.7 0-32-14.3-32-32V329.1l-18.1 40.6c-5.4 12.1-19.6 17.6-31.7 12.2s-17.5-19.5-12.1-31.6L24 300.9c5.3-11.9 8-24.7 8-37.7C32 155.7 117.2 68 223.8 64.1l.2-.1h64c41.7 0 83.4 12.1 117.2 25.7 1.7-1.8 3.5-3.6 5.3-5.2L407 81c-9.4-9.4-9.4-24.6 0-33.9zm73 185a24 24 0 1 0-48 0 24 24 0 1 0 48 0zm88 24a24 24 0 1 0 0-48 24 24 0 1 0 0 48zm-88-112a16 16 0 1 0-32 0 16 16 0 1 0 32 0zm48 16a16 16 0 1 0 0-32 16 16 0 1 0 0 32z"/>
</svg>
<!-- 省略其他 SVG 图标 -->
</svg>这个时候,你可以像下面这样在 HTML 和 CSS 使用 sprite.svg 中的图标:
<body>
<img src="sprite-stack.svg#twitter" alt="" />
<img src="sprite-stack.svg#github" alt="" />
<div class="icon icon--hippo"></div>
<div class="icon icon--umbrella"></div>
</body>body {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(min(100% - 2rem, 300px), 1fr));
gap: 2rem;
}
.icon, img {
display: block;
width: 100%;
aspect-ratio: 1;
}
.icon--hippo {
background: url("sprite-stack.svg#animals--hippo") no-repeat;
}
.icon--umbrella {
background: url("sprite-stack.svg#weather--umbrella") no-repeat;
}最后一种是 SVG 视图(<view> )的使用方式。
// gulpfile.js
const config = {
mode: {
view: {
dest: 'sprite',
sprite: 'sprite.svg',
example: true
},
}
};生成的 sprite.svg 中会有一个带有 id 名的 <view> :
<svg width="3328" height="2560" viewBox="0 0 3328 2560" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<view id="animals--feather" viewBox="1152 1024 512 512"/>
<svg viewBox="0 0 512 512" width="512" height="512" x="1152" y="1024" xmlns="http://www.w3.org/2000/svg">
<path d="M278.5 215.6 23 471c-9.4 9.4-9.4 24.6 0 33.9s24.6 9.4 33.9 0l57-57h68c49.7 0 97.9-14.4 139-41 11.1-7.2 5.5-23-7.8-23-5.1 0-9.2-4.1-9.2-9.2 0-4.1 2.7-7.6 6.5-8.8l81-24.3c2.5-.8 4.8-2.1 6.7-4l22.4-22.4c10.1-10.1 2.9-27.3-11.3-27.3H377c-5.1 0-9.2-4.1-9.2-9.2 0-4.1 2.7-7.6 6.5-8.8l112-33.6c4-1.2 7.4-3.9 9.3-7.7 10.8-21 16.4-44.5 16.4-68.6 0-41-16.3-80.3-45.3-109.3l-5.5-5.5C432.3 16.3 393 0 352 0s-80.3 16.3-109.3 45.3L139 149c-48 48-75 113.1-75 181v55.3l189.6-189.5c6.2-6.2 16.4-6.2 22.6 0 5.4 5.4 6.1 13.6 2.2 19.8z"/>
</svg>
<view id="animals--hippo" viewBox="0 0 640 512"/>
<svg viewBox="0 0 640 512" width="640" height="512" xmlns="http://www.w3.org/2000/svg">
<path d="M407 47c9.4-9.4 24.6-9.4 33.9 0l17.2 17.2c1.9-.1 3.9-.2 5.8-.2h32c11.2 0 21.9 2.3 31.6 6.5L543 55c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9l-12.9 13c7.6 12.2 12 26.7 12 42.1 0 10.2 7.4 18.8 16.7 23 27.9 12.5 47.3 40.5 47.3 73 0 26.2-12.6 49.4-32 64v32c0 8.8-7.2 16-16 16h-32c-8.8 0-16-7.2-16-16v-16h-64v16c0 8.8-7.2 16-16 16h-32c-8.8 0-16-7.2-16-16v-17.6c-11.8-2.4-22.7-7.4-32-14.4-1.5-1.1-2.9-2.3-4.3-3.5-17-14.7-27.7-36.4-27.7-60.5 0-8.8-7.2-16-16-16s-16 7.2-16 16c0 44.7 26.2 83.2 64 101.2V352c0 17.7 14.3 32 32 32h32v64c0 17.7-14.3 32-32 32h-64c-17.7 0-32-14.3-32-32v-76c-19.8 7.7-41.4 12-64 12s-44.2-4.3-64-12v76c0 17.7-14.3 32-32 32H96c-17.7 0-32-14.3-32-32V329.1l-18.1 40.6c-5.4 12.1-19.6 17.6-31.7 12.2s-17.5-19.5-12.1-31.6L24 300.9c5.3-11.9 8-24.7 8-37.7C32 155.7 117.2 68 223.8 64.1l.2-.1h64c41.7 0 83.4 12.1 117.2 25.7 1.7-1.8 3.5-3.6 5.3-5.2L407 81c-9.4-9.4-9.4-24.6 0-33.9zm73 185a24 24 0 1 0-48 0 24 24 0 1 0 48 0zm88 24a24 24 0 1 0 0-48 24 24 0 1 0 0 48zm-88-112a16 16 0 1 0-32 0 16 16 0 1 0 32 0zm48 16a16 16 0 1 0 0-32 16 16 0 1 0 0 32z"/>
</svg>
<!-- 省略其他 SVG 图标 -->
</svg>你会发现,一个 SVG 图标对应一个 <svg> 和 <view> 元素。然后你可以像下面这样使用:
<img src="sprite-view-25133bf8.svg#twitter" alt="" style="aspect-ratio: 512 / 512" />
<img src="sprite-view-25133bf8.svg#svgView(viewBox(0 ,0, 640, 512))" alt="" style="aspect-ratio: 640 / 512;" />
<div class="icon icon--spider"></div>
<div class="icon icon--facebook"></div>body {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(min(100% - 2rem, 300px), 1fr));
gap: 2rem;
}
.icon, img {
display: block;
width: 100%;
}
.icon {
background-size: 100% 100% !important;
}
img {
object-fit: cover;
}
.icon--spider {
background: url("sprite-view-25133bf8.svg#animals--spider") no-repeat;
aspect-ratio: 1;
}
.icon--facebook {
background: url("sprite-view-25133bf8.svg#svgView(viewBox(1856, 1024, 448, 512))") no-repeat;
aspect-ratio: 448 / 512;
} 这种技术将使用 SVG 的 viewBox 属性将 SVG 雪碧图裁剪到指定的图标。这种技术 除了能够引用外部 SVG 并因此利用浏览器缓存之外,它还允许我们使用几乎任何 SVG 嵌入技术,并且不限制我们使用特定的标签。不用说,这个功能不仅可以用于图标系统,还可以用于其他用途,因为 viewBox 在控制SVG的可视区域方面非常强大。
使用 SVG 片段标识符和视图时,与内联 SVG 雪碧图不同,我们无法直接使用 CSS 对 SVG 进行样式设置。
首先需要明确的一点是,如果我们要将 SVG 雪碧图的图标以内联 CSS 的方式或 SVG 片段标识符的方式应用于 Web,那么直接使用 SVG 元素的“演示属性”来为SVG图标设置样式就会变得相对困难。不过,你可以借助现代 CSS 特性中的处理图像特效的相关属性(如 filter 、mix-blend-mode 、background-blend-mode 等)来调整图标的样式。例如下面这个示例是使用 filter 调整 SVG 图标的颜色:
<div class="icon"></div>:root {
--icon: url("data:image/svg+xml;base64,PD94bWw...");
}
.icon {
--invert: 0;
--sepia: 0;
--saturate: 1;
--hueRotate: 0;
--brightness: 1;
filter: invert(var(--invert)) sepia(var(--sepia)) saturate(var(--saturate))
hue-rotate(calc(var(--hueRotate) * 1turn)) brightness(var(--brightness));
}接下来,我们着重聊聊 CSS 如何给内联 SVG 雪碧图设置样式。
<body>
<!-- 引用 SVG 图标 -->
<svg class="icon icon--dribbble">
<use href="#dribbble" />
</svg>
<!-- 创建 SVG 雪碧图 -->
<svg class="sr-only">
<symbol viewBox="0 0 448 512" id="dribbble">
<path d="M165.9 132.5c-38.3 18-66.8 53.3-75.7 95.7c6.1 .1 62.4 .3 126.4-16.7c-22.7-40.2-47.1-74.1-50.7-79zm26.1-9.1c3.8 5.1 28.6 38.9 51 80c48.6-18.3 69.1-45.9 71.6-49.4C281 124.2 235.3 112.9 192 123.4zM277.4 382c-2-12-10-53.8-29.2-103.6c-55.1 18.8-93.8 56.4-108.1 85.6c40.5 31.6 93.3 36.7 137.3 18zM227.8 232.6C159.6 253 93.4 252.2 87.4 252c0 .7 0 1.4 0 2.1s0 1.4 0 2.1c0 35.1 13.3 67.1 35.1 91.4c22.2-37.9 67.1-77.9 116.5-91.8c-3.4-7.8-7.2-15.5-11.1-23.2zm72.5 136.9c30.7-20.7 52.5-53.6 58.6-91.6c-4.6-1.5-42.3-12.7-85.1-5.8c17.9 49.1 25.1 89.1 26.5 97.4zm-34.8-119c45.5-5.7 90.7 3.4 95.2 4.4c-.3-32.3-11.8-61.9-30.9-85.1c-2.9 3.9-25.8 33.2-76.3 53.9c4.8 9.8 8.3 17.8 12 26.8zM384 32H64C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64zM224 416a160 160 0 1 1 0-320 160 160 0 1 1 0 320z" />
</symbol>
<symbol viewBox="0 0 448 512" id="facebook">
<path d="M64 32C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64h98.2V334.2H109.4V256h52.8V222.3c0-87.1 39.4-127.5 125-127.5c16.2 0 44.2 3.2 55.7 6.4V172c-6-.6-16.5-1-29.6-1c-42 0-58.2 15.9-58.2 57.2V256h83.6l-14.4 78.2H255V480H384c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H64z" />
</symbol>
<!-- 其他 SVG 图标 -->
</svg>
</body>我们从基础样式开始。示例在给 SVG 雪碧图添加了一个 sr-only 类名,使用 SVG 图标时添加了一个 icon 类名。在 CSS 中给这两个通用类设置了以下样式:
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border-width: 0;
}
.icon {
display: block;
width: 1em;
aspect-ratio: var(--ratio, 1); /* 对应 viewBox 中的 width 和 height*/
fill: currentColor;
}.sr-only 主要是为了隐藏 SVG 雪碧图,这样做是使 SVG 雪碧图不占用页面的任何空间(虽然 <symbol> 绘制的图标不会在 SVG 画布上呈现),避免打破 Web 布局。
.icon 是应用图标的基本样式。<svg> 元素的 vertical-align 默认值是 baseline ,这会在图标留下几个像素的空白(大约是 4px)。可以通过重置 display 的值为 block 来避免这种情况出现。除此之外,你还可以显式设置 vertical-align 的值,只要不是默认值 baseline 即可。如果与文本一起使用,你可以将 vertical-align 设置为 -4px (或 -0.15em)。
通常情况下,<symbol> 创建的 SVG 图标是以 viewBox 中的 <width> 和 <height> 来定义图标的尺寸大小。可以在通用类名 .icon 中使用 width 和 aspect-ratio 来设置图标的尺寸大小。
.icon {
width: 1em;
aspect-ratio: var(--ratio, 1);
}上面这样设置,SVG 图标会随着元素的 font-size 调整大小,注意,aspect-ratio 的值最好与 <symbol> 元素的 viewBox 中的 <width> 和 <height> 值相匹配。
fill:currentColor 使得 SVG 图标的颜色与 color 同步:
.icon--dribbble {
color: lime;
}
.icon--facebook {
color: red;
}正如你所看到的,我们现在只需要调整 font-size 就可以改变图标的大小,调整 color 就可以改变图标的颜色。
另外,SVG 样式属性是可继承的,例如上面示例中的 fill 属性。当我们在 <svg> 元素上设置 fill 属性的值,它的后代元素(如示例中的 <path>)元素也会继承它的值。如此一来,使用这个技术,可以在 CSS 中处理图标的其他样式,例如描边样式:
.icon {
fill: none;
stroke: currentColor;
stroke-width: 10px;
stroke-linecap: round;
stroke-linejoin: round;
}细心的你可能已经发现了,上面示例中图标描边的效果并不怎么均匀,看上去有部分被裁剪了一样。这是因为,在 SVG 中,描边总是在路径的两侧(内部和外部)绘制。如果你的路径接触到视口的限制,一半的描边将被裁剪掉。这也是为什么在设计 SVG 图标时,要在绘制的形状周围留出一些空间的原因所在。
另外,给 SVG 描边设置合适的大小是技术活。例如,下面这个示例,在 <svg> 图标上设置了 stroke-width: 1px :
<svg class="sr-only">
<symbol id="heart" viewBox="0 0 20 20">
<path d="M18.98 5.7c-.24-2.36-2.24-4.2-4.66-4.2-1.95 0-3.6 1.18-4.32 2.87-.7-1.7-2.37-2.87-4.32-2.87-2.42 0-4.42 1.84-4.66 4.2L1 6.18c0 5.7 6.98 8.38 9 12.17 2.02-3.8 9-6.48 9-12.17 0-.16 0-.32-.02-.48z" />
</symbol>
<symbol id="heart2" viewBox="0 0 500 500">
<path d="M474.4 142.8c-6-59-55.8-105-116.5-105-48.6 0-90.3 29.5-108 71.7-17.7-42.2-59.4-71.8-108-71.8-60.6 0-110.4 46-116.4 105-.4 4-.6 8-.6 12C25 297 199.5 364.3 250 459c50.5-94.8 225-162 225-304.2 0-4-.2-8-.6-12z" />
</symbol>
</svg>
<svg class="icon icon--heart">
<use href="#heart" />
</svg>
<svg class="icon icon--heart2">
<use href="#heart2" />
</svg>.icon {
stroke-width: 1px;
}不难发现,stroke-width 接受同一个“长度”值 1px ,左侧描边比右侧描边明显要粗很多。这是因为该值相对于图标的局部坐标:
viewBox 是 0 0 20 20 ,因此,1px 的描边是图标尺寸的 1/20 ,viewBox 要填满整个 Viewport,因此会放大,相应的图形也会放大,描边也相应的变粗viewBox 是 0 0 500 500 ,因此, 1px 的描边是图标尺寸的 1/500 ,viewBox 要相应缩小才可以填满整个 Viewport,相应的图形也会缩小,描边也相应的变细这意味着,如果图标的 viewBox 大小差异很大,stroke-width 使用像素或无单位的值,就会出现上面示例这种现象。在这种情景中,可以考虑将 stroke-width 的值设置为百分比值(%)。但需要知道 stroke-width 取百分比值是如何计算的。
事实证明,stroke-width 取百分比值时,它是相对于 viewBox 对角线的长度计算(sqrt((width)**2 + (height)**2)/sqrt(2) ,其中 width 和 height 分别是 viewBox 属性的 <width> 和 <height>)。当 viewBox 是一个正方形,该公式的结果是正方形的一边。因此,1% 表示“宽度的百分之一或高度的百分之一”。当 viewBox 是一个长方形(宽或高不相等),结果将根据上面的公式来计算。
注意,刚才提到给图标设置 stroke-width 可能会使得图标边缘被 viewBox 裁剪,除了在设计图标时考虑预留一定空间之外,还可以通过调整 viewBox 的值。这也再次彰显了 viewBox 在 SVG 中的重要性。
上面我们在讨论 CSS 如何样式化 SVG 图标时,它们都有一个前提条件,那就是 <symbol> 元素实例化图标时,该元素上没有设置与样式有关的任何属性,哪怕是“演示属性”。但我们在获取图标时,有些图标会自带“演示属性”,例如 fill 属性。此时,即使你在 CSS 中设置了 fill 属性,你也将无法覆盖 <symbol> 元素自带的样式。例如:
<svg class="icon icon--flower">
<use href="#flower" />
</svg>
<svg class="sr-only">
<symbol id="flower" viewBox="0 0 1024 1024">
<path d="M372.362 286.38h42.674v133.552h-42.674zM887.206 54.826h42.674v115.028h-42.674zM609.758 148.174h42.676v115.028h-42.676z" fill="#8CC153" />
<path d="M888.706 304.906v71.354c0 11.778 9.56 21.338 21.338 21.338s21.336-9.56 21.336-21.338v-71.354h-42.674zM611.29 469.608a21.326 21.326 0 0 0 21.338 21.336c11.778 0 21.338-9.558 21.338-21.336v-71.384h-42.676v71.384zM373.862 554.958v71.382c0 11.778 9.56 21.338 21.336 21.338 11.808 0 21.336-9.56 21.336-21.338v-71.382h-42.672z" fill="#E6E9ED" />
<path d="M1007.324 163.418c-12.402-14.244-30.272-21.804-51.704-21.804-21.054 0-35.77 11.464-45.828 24.554-10.248-13.058-25.086-24.554-46.08-24.554-20.776 0-38.894 7.748-51.016 21.774-13.872 16.028-19.15 38.394-15.308 64.73 3.56 24.338 16.026 49.142 35.084 69.822 20.21 21.962 46.266 37.084 73.382 42.52l4.218 0.876 4.216-0.876c27.116-5.466 53.202-20.556 73.448-42.488 19.18-20.742 31.614-45.61 35.02-69.978 4.658-33.334-5.808-53.516-15.432-64.576zM678.208 234.958c-21.056 0-35.77 11.466-45.83 24.554-10.248-13.056-25.086-24.554-46.112-24.554-20.742 0-38.864 7.748-51.016 21.776-13.84 16.026-19.12 38.394-15.278 64.7 3.562 24.368 15.996 49.172 35.052 69.854 20.244 21.96 46.298 37.05 73.416 42.518l4.186 0.844 4.216-0.844c27.148-5.466 53.234-20.556 73.478-42.486 19.15-20.776 31.584-45.612 35.022-70.01 4.652-33.302-5.812-53.484-15.434-64.542-12.4-14.248-30.302-21.81-51.7-21.81zM492.482 413.498c-12.402-14.276-30.272-21.804-51.704-21.804-21.056 0-35.74 11.464-45.83 24.554-10.248-13.058-25.086-24.554-46.08-24.554-20.776 0-38.894 7.748-51.016 21.774-13.838 15.996-19.12 38.394-15.276 64.7 3.53 24.37 15.996 49.142 35.052 69.854 20.212 21.962 46.298 37.052 73.384 42.52l4.218 0.844 4.218-0.844c27.116-5.466 53.234-20.556 73.478-42.488 19.15-20.774 31.584-45.61 34.99-70.01 4.684-33.336-5.812-53.486-15.434-64.546z" fill="#EC87C0" />
<path d="M52.022 473.012c5 4.374 31.616 26.368 65.106 30.99 3.936 0.532 9.904 1.406 16.246 2.344 31.366 4.624 41.488 5.966 48.048 5.966 1.094 0 2.156-0.032 3.186-0.094h18.494l10.528-13.496c1.592-1.562 2.842-2.966 3.75-3.966 1.936-2.188 4.436-5.154 7.622-8.998 5.5-6.624 12.214-14.964 18.152-22.336 4.03-5 7.84-9.716 10.372-12.778 21.462-26.118 26.086-60.326 26.804-66.95l5.498-51.328-27.148 2.25c-1-5.342-1.938-8.936-2.25-9.998l-16.962-61.636-38.55 30.052-28.428-52.546-22.31 27.43c-5.312-5.436-9.186-8.778-10.278-9.714l-59.888-50.266-9.904 77.538c-0.188 1.438-0.782 6.56-1 14.184l-35.052-4.998 14.776 57.858L0.1 356.61l29.366 56.794c0.532 1 2.25 4.25 5.156 8.842l-21.494 16.776 38.894 33.99zM331.812 842.398l-27.368-28.928c11.966-8.154 19.494-14.87 21.182-16.4l57.608-52.89-75.634-19.87c-1.562-0.406-11.558-2.936-26.46-4.624l10.714-38.458-63.386 7.684c-0.906 0.094-2.968 0.376-5.966 0.844l2.624-56.7L164.988 654.8c-1.686 0.624-8.748 3.282-18.338 8.214l-15.496-26.272-38.738 34.146c-5.718 5.058-34.708 32.05-44.862 69.226-1.282 4.718-3.312 11.81-5.436 19.34-3.124 11.09-6.686 23.648-9.404 33.708a586.548 586.548 0 0 0-3.5 13.622c-0.406 1.812-0.968 4.188-1.374 7.03l-2.468 8.78 2.25 7.058 0.594 10.592 8.498 8.654c1.594 2.188 3.124 3.904 4.28 5.248 2.25 2.592 5.342 5.998 9.434 10.402 7.124 7.654 16.12 17.088 24.054 25.398 5.406 5.654 10.528 10.998 13.84 14.558 26.368 28.116 64.636 38.426 72.04 40.236l50.172 12.092 1.468-30.458c10.966-0.156 18.526-1.124 20.026-1.344l63.324-8.842-28.834-48.922c2.968-1 4.936-1.75 5.686-2.032l59.608-22.836z" fill="#8CC153" />
<path d="M1023.882 21.494c0-11.808-9.558-21.338-21.338-21.338-1.03 0-2.06 0.094-3.06 0.218-2.5 0.344-62.136 9.186-152.36 35.832-83.102 24.526-208.75 69.45-335.462 144.3-142.988 84.444-258.14 188.91-342.27 310.498C64.05 643.242 7.566 822.5 1.444 1023.844h42.706c6.06-192.16 59.856-363.044 159.888-507.906 80.414-116.434 190.816-216.686 328.15-298.004 122.84-72.698 244.926-116.496 325.684-140.426 87.786-25.992 147.174-34.834 147.766-34.896v-0.032c10.31-1.498 18.244-10.372 18.244-21.086z" fill="#A0D468" />
</symbol>
</svg>.icon {
display: block;
width: 1em;
aspect-ratio: var(--ratio, 1);
fill: currentColor;
}
.icon--flower {
color:yellow;
font-size: 30vw;
}你会发现,.icon--flower 中的样式没法覆盖 <symbol> 中 <path> 元素的 fill 值。
这是因为 <use> 的后代元素都是 Shadow DOM,普通的 CSS 选择器是无法穿透 Shadow DOM。因此,我们需要人为去干涉,比如删除 <symbol> 后代元素(绘制图形相关元素)上的所有与样式有关的属性,包括演示属性。如果你的图标和上面示例所呈现的一样,是一个多色的图标,那么仅仅删除元素上的样式属性还是不够的。这个时候我们需要使用更高级的技术,使用 CSS 自定义属性来描述元素的样式属性的值。比如,上面的花,可以这样来修改:
<svg class="sr-only">
<symbol id="flower" viewBox="0 0 1024 1024">
<path fill="var(--fill-color1,#8CC153)" d="M372.362 286.38h42.674v133.552h-42.674zM887.206 54.826h42.674v115.028h-42.674zM609.758 148.174h42.676v115.028h-42.676z" />
<path fill="var(--fill-color2, #E6E9ED)" d="M888.706 304.906v71.354c0 11.778 9.56 21.338 21.338 21.338s21.336-9.56 21.336-21.338v-71.354h-42.674zM611.29 469.608a21.326 21.326 0 0 0 21.338 21.336c11.778 0 21.338-9.558 21.338-21.336v-71.384h-42.676v71.384zM373.862 554.958v71.382c0 11.778 9.56 21.338 21.336 21.338 11.808 0 21.336-9.56 21.336-21.338v-71.382h-42.672z" />
<path fill="var(--fill-color3, #EC87C0)" d="M1007.324 163.418c-12.402-14.244-30.272-21.804-51.704-21.804-21.054 0-35.77 11.464-45.828 24.554-10.248-13.058-25.086-24.554-46.08-24.554-20.776 0-38.894 7.748-51.016 21.774-13.872 16.028-19.15 38.394-15.308 64.73 3.56 24.338 16.026 49.142 35.084 69.822 20.21 21.962 46.266 37.084 73.382 42.52l4.218 0.876 4.216-0.876c27.116-5.466 53.202-20.556 73.448-42.488 19.18-20.742 31.614-45.61 35.02-69.978 4.658-33.334-5.808-53.516-15.432-64.576zM678.208 234.958c-21.056 0-35.77 11.466-45.83 24.554-10.248-13.056-25.086-24.554-46.112-24.554-20.742 0-38.864 7.748-51.016 21.776-13.84 16.026-19.12 38.394-15.278 64.7 3.562 24.368 15.996 49.172 35.052 69.854 20.244 21.96 46.298 37.05 73.416 42.518l4.186 0.844 4.216-0.844c27.148-5.466 53.234-20.556 73.478-42.486 19.15-20.776 31.584-45.612 35.022-70.01 4.652-33.302-5.812-53.484-15.434-64.542-12.4-14.248-30.302-21.81-51.7-21.81zM492.482 413.498c-12.402-14.276-30.272-21.804-51.704-21.804-21.056 0-35.74 11.464-45.83 24.554-10.248-13.058-25.086-24.554-46.08-24.554-20.776 0-38.894 7.748-51.016 21.774-13.838 15.996-19.12 38.394-15.276 64.7 3.53 24.37 15.996 49.142 35.052 69.854 20.212 21.962 46.298 37.052 73.384 42.52l4.218 0.844 4.218-0.844c27.116-5.466 53.234-20.556 73.478-42.488 19.15-20.774 31.584-45.61 34.99-70.01 4.684-33.336-5.812-53.486-15.434-64.546z" />
<path fill="var(--fill-color1,#8CC153)" d="M52.022 473.012c5 4.374 31.616 26.368 65.106 30.99 3.936 0.532 9.904 1.406 16.246 2.344 31.366 4.624 41.488 5.966 48.048 5.966 1.094 0 2.156-0.032 3.186-0.094h18.494l10.528-13.496c1.592-1.562 2.842-2.966 3.75-3.966 1.936-2.188 4.436-5.154 7.622-8.998 5.5-6.624 12.214-14.964 18.152-22.336 4.03-5 7.84-9.716 10.372-12.778 21.462-26.118 26.086-60.326 26.804-66.95l5.498-51.328-27.148 2.25c-1-5.342-1.938-8.936-2.25-9.998l-16.962-61.636-38.55 30.052-28.428-52.546-22.31 27.43c-5.312-5.436-9.186-8.778-10.278-9.714l-59.888-50.266-9.904 77.538c-0.188 1.438-0.782 6.56-1 14.184l-35.052-4.998 14.776 57.858L0.1 356.61l29.366 56.794c0.532 1 2.25 4.25 5.156 8.842l-21.494 16.776 38.894 33.99zM331.812 842.398l-27.368-28.928c11.966-8.154 19.494-14.87 21.182-16.4l57.608-52.89-75.634-19.87c-1.562-0.406-11.558-2.936-26.46-4.624l10.714-38.458-63.386 7.684c-0.906 0.094-2.968 0.376-5.966 0.844l2.624-56.7L164.988 654.8c-1.686 0.624-8.748 3.282-18.338 8.214l-15.496-26.272-38.738 34.146c-5.718 5.058-34.708 32.05-44.862 69.226-1.282 4.718-3.312 11.81-5.436 19.34-3.124 11.09-6.686 23.648-9.404 33.708a586.548 586.548 0 0 0-3.5 13.622c-0.406 1.812-0.968 4.188-1.374 7.03l-2.468 8.78 2.25 7.058 0.594 10.592 8.498 8.654c1.594 2.188 3.124 3.904 4.28 5.248 2.25 2.592 5.342 5.998 9.434 10.402 7.124 7.654 16.12 17.088 24.054 25.398 5.406 5.654 10.528 10.998 13.84 14.558 26.368 28.116 64.636 38.426 72.04 40.236l50.172 12.092 1.468-30.458c10.966-0.156 18.526-1.124 20.026-1.344l63.324-8.842-28.834-48.922c2.968-1 4.936-1.75 5.686-2.032l59.608-22.836z" />
<path fill="var(--fill-color4, #A0D468)" d="M1023.882 21.494c0-11.808-9.558-21.338-21.338-21.338-1.03 0-2.06 0.094-3.06 0.218-2.5 0.344-62.136 9.186-152.36 35.832-83.102 24.526-208.75 69.45-335.462 144.3-142.988 84.444-258.14 188.91-342.27 310.498C64.05 643.242 7.566 822.5 1.444 1023.844h42.706c6.06-192.16 59.856-363.044 159.888-507.906 80.414-116.434 190.816-216.686 328.15-298.004 122.84-72.698 244.926-116.496 325.684-140.426 87.786-25.992 147.174-34.834 147.766-34.896v-0.032c10.31-1.498 18.244-10.372 18.244-21.086z" />
</symbol>
</svg>这个时候,你只需要在 CSS 改变自定义属性的值即可:
.icon--flower {
--fill-color1: red;
--fill-color2: orange;
--fill-color3: yellow;
--fill-color4: lime;
}另外,除了纯色填充之外,还可以是渐变色和纹理等:
有关这方面更详细的介绍,我们会在后续的课程中与大家一起探讨!
现在,你已经掌握了使用 SVG 创建自己的图标系统的所有环节。从设计图标(或获取图标)到创建雪碧图,再到将图标集成到 Web 应用或网站上,最后样式化图标。除此之外,你还掌握了自动化创建图标系统的方法。在后续的实战课中,我们还将进一步探讨,你创建的图标系统在各个技术框架中如何使用。