SVG 指南

SVG 用作图像的优缺点

当用作文档格式时,通常有一个令人信服的理由使 SVG 成为唯一的解决方案。当用作图像格式时,有时不太清楚对于任何给定的图像,使用 SVG 还是光栅图像格式是最佳选择。矢量格式 SVG 和光栅格式(如 PNG)都有其应用场景。在选择是否使用 SVG 时,最好了解两者的优缺点。

文件大小

对于给定的图像,SVG 或光栅格式是否会生成更小的文件很大程度上取决于图像本身。例如,考虑一个带有渐变填充的路径图像。此图像的 SVG 大小与图像尺寸无关。另一方面,相同图像的光栅文件大小可能会根据图像尺寸而发生巨大变化,因为尺寸越大,文件需要存储的像素数据就越多。在非常小的尺寸(极端情况为 1px x 1px)下,光栅文件可能比 SVG 文件小得多,因为它只需要存储一个像素的数据。在较大的尺寸下,光栅文件可能比 SVG 文件大得多。

可伸缩性,带有一些注意事项

SVG 的主要优点之一是,在缩放时不会出现像素化。但是,这并不是说它总是可以避免为不同比例的显示提供一系列光栅图像。这对于图标尤其如此。虽然 SVG 对于没有太多细节的扁平化图标可能缩放效果很好,但对于试图包含大量细节的图标,图形艺术家通常希望能够进行像素调整

性能

虽然 SVG 在缩放、主题化等方面提供了很大的灵活性,但这种灵活性依赖于在显示 SVG 图像时进行计算,而不是在作者创建它们时进行计算。考虑一个包含一些复杂渐变和滤镜的图像。如果将其保存为光栅图像,则光栅化渐变和滤镜的工作将在作者的计算机上完成,然后将结果存储在光栅文件中。在其他人电脑上显示图像时,不需要重新执行此工作。另一方面,如果图像保存为 SVG 图像,则每次在其他人电脑上显示 SVG 时都需要执行所有这些工作。这并不是说 SVG 图像总是比光栅等效图像慢。事实上,从 SVG 发送矢量信息到用户的 GPU 比从等效的光栅图像中提取光栅数据更快。即使 SVG 图像比光栅等效图像慢,差异通常也不明显。但是,不要陷入 SVG 比等效的光栅图像快,反之亦然的误区。“视情况而定”。

创作指南

许多 SVG 文件(特别是那些由 SVG 编辑器生成的)在未清理的情况下发布,并且可能包含大量垃圾,这些垃圾会增加文件大小并降低渲染速度。通常,解决此问题的最佳方法是首先使用 linter(例如 svgo(请参阅下面的“工具”部分))运行 SVG 文件。但是,当手动创作 SVG 时,以下是一些有助于保持其轻量级的最佳实践。这些规则基于在 Mozilla 代码中看到的一些真实示例。

基础知识

  • 使用两个空格缩进

  • 不要使用无用的空格或换行符(有关更多详细信息,请参阅下文)

  • 添加许可证头部

  • 使用双引号

空格和换行符

空格

除了行尾的尾随空格外,还有几个更特定于 SVG 的情况

  • 属性值中的尾随空格(通常在路径定义中看到)

  • 路径或多边形点定义中的过多空格

空格示例

此路径

<path d=" M5,5    L1,1z ">

可以简化为

<path d="M5,5 L1,1z">

类似地,此多边形

<polygon points="  0,0   4,4  4,0  "/>

可以简化为

<polygon points="0,0 4,4 4,0"/>

换行符

您应该仅在逻辑分隔或有助于提高文件可读性时使用换行符。您应该避免在每个元素之间或属性值内使用换行符。建议在可能的情况下将属性放在与其标签名称相同的行上。您还应该先放置最短的属性,以便更容易发现它们。

未使用的标签和属性

编辑器元数据

矢量编辑器(Inkscape、Adobe Illustrator、Sketch)通常在保存 SVG 文件时会在其中添加大量元数据。元数据可以表示许多内容,包括

  • 典型的“使用 编辑器 创建”注释

  • 非标准的编辑器特定标签和属性(sketch:fooillustrator:foosopodi:foo 等)

  • 附带后者的XML 命名空间定义(xmlns:sketchxmlns:sopodi 等)

其他元数据

除了非标准的编辑器元数据外,还存在符合标准的元数据。这方面的典型示例是 <title><desc> 标签。尽管浏览器支持这种数据,但只有在 SVG 在新标签页中打开时才能显示。此外,在大多数情况下,文件名具有描述性,因此建议删除此类元数据,因为它没有带来太多价值。

您也不应该在 SVG 中包含 DOCTYPE;它们是许多问题的根源,SVG 工作组建议不要包含它们。请参阅SVG 创作指南

避免使用 CDATA 部分

CDATA 部分用于避免将某些文本解析为 HTML。大多数情况下,不需要 CDATA,例如,<style> 标签中的内容不需要包装在 CDATA 部分中,因为标签内的内容已正确解析为 CSS。

不可见的形状

有两种类型的不可见形状:屏幕外的形状和未着色的形状。

屏幕外形状很难发现,即使使用自动化工具,并且通常是上下文相关的。这些类型的形状是可见的,但位于SVG 视区之外。这是一个示例,其中包含屏幕外形状。

另一方面,未着色的形状更容易发现,因为它们通常带有使它们不可见的样式。它们必须满足两个条件:它们必须没有填充(或透明填充)或描边。

<svg> 元素上的未使用属性

<svg> 元素还可以承载许多无用的属性。考虑到以下列表,这是一个示例

  • 版本

  • x="0"y="0"

  • enable-background(Gecko 不支持,并且现在已由 Filter Effects 规范弃用)

  • id(根元素上的 id 无效)

  • 在整个文件中未使用任何 xlink:href 属性时,xmlns:xlink 属性

  • 其他未使用的XML 命名空间定义

  • xml:space(当文件中未使用文本时)

其他

  • 空标签,这可能是显而易见的,但有时会在 SVG 中找到

  • 未引用的 id(通常在渐变停止处,但也存在于形状或路径上)

  • clip-rule 属性(当元素不是<clipPath> 的后代时)

  • fill-rule 属性(当元素<clipPath> 的后代时)

  • 未引用/未使用的剪辑路径、蒙版或 defs(示例

样式

样式基础

  • 优先使用短小写的十六进制表示颜色

  • 不要对数值使用过多的精度(通常来自 Illustrator)

  • 使用描述性 ID

  • 避免内联样式,并使用类名或 SVG 属性

样式示例

以下是一些关于过度数字精度的示例

  • 5.000000e-02 → 0.05(如此处所示)

  • -3.728928e-10 → 0(如此处所示)

  • translate(0.000000, -1.000000) → translate(0, -1)(如此处所示)

对于描述性 ID

  • 对于渐变:SVG_ID1 → gradient1(如此处所示)

类名的使用

  • 如果该类在文件中仅使用一次,则避免使用它

  • 如果该类仅设置填充或描边,最好直接在实际形状上设置填充/描边,而不是仅为该形状引入一个类。您还可以使用 SVG 分组来避免重复这些属性

  • 避免引入相同文件的变体(颜色/样式变体),并使用精灵图代替(使用类名)

默认样式值

通常不需要设置默认样式值,除非您要覆盖某个样式。以下是一些常见的示例

  • style="display: none;" 用于 <defs> 元素(<defs> 元素默认是隐藏的)

  • type="text/css" 用于 <style> 元素

  • stroke: nonestroke-width: 0

SVG 分组

样式分组

将具有相似样式的图形组合在一个 <g> 标签下;这样可以避免在多个图形上设置相同的类/样式。

避免过度分组

编辑器在导出 SVG 时有时会进行过度分组。这是由于编辑器的工作方式造成的。

嵌套组

避免多层嵌套组,这些会降低 SVG 的可读性。

嵌套变换

某些编辑器使用 <g> 标签进行嵌套变换,这通常是不必要的。您可以通过进行基本的代数运算来避免这种情况,例如

<g transform="translate(-62, -310)"><shape transform="translate(60, 308)"/></g>

可以简化为

<shape transform="translate(-2,-2)"/>

因为:-62+60 = -310+308 = -2

性能提示

这些规则是可选的,但它们有助于加快 SVG 的速度。

  • <use> 标签在整个文件中只被引用一次时,避免使用 <use> 标签。

  • 不要使用 CSS/SVG 变换,而应直接在路径/图形定义上应用变换。

工具

工具可以帮助清理 SVG 文件。但是请注意,上面列出的一些规则很难用自动化工具检测到,因为它们需要太多的上下文感知。到目前为止,似乎还没有一个工具可以处理上述所有内容。但是,有一些实用程序涵盖了本文档的部分内容