在 HTML 中包含矢量图形
矢量图形在很多情况下都非常有用——它们文件大小小,而且高度可伸缩,因此在放大或放大到大尺寸时不会像素化。在本文中,我们将向您展示如何将矢量图形包含在您的网页中。
注意:本文无意教授您 SVG;只是介绍它是什么,以及如何将其添加到网页中。
什么是矢量图形?
在 Web 上,您将处理两种类型的图像——栅格图像和矢量图像。
- 栅格图像是使用像素网格定义的——栅格图像文件包含显示每个像素精确放置位置以及精确颜色的信息。流行的 Web 栅格格式包括位图(
.bmp)、PNG(.png)、JPEG(.jpg)和 GIF(.gif)。 - 矢量图像是使用算法定义的——矢量图像文件包含形状和路径定义,计算机可以使用这些定义来计算图像在屏幕上渲染时的外观。SVG 格式允许我们创建强大的矢量图形以用于 Web。
为了让您了解两者之间的区别,我们来看一个例子。您可以在我们的 GitHub 仓库中找到这个实时示例,名为 vector-versus-raster.html — 它并排显示了两个看似相同的图像,都是带有黑色阴影的红色星星。不同之处在于左边的是 PNG,右边的是 SVG 图像。
当您放大页面时,差异就会显现出来——PNG 图像在放大时会变得像素化,因为它包含每个像素应该在哪里(以及什么颜色)的信息。当它被放大时,每个像素的尺寸都会增加以填充屏幕上的多个像素,因此图像开始看起来呈块状。然而,矢量图像继续保持清晰美观,因为无论它有多大,都会使用算法来计算图像中的形状,并且随着它的变大,值也会相应缩放。


注意:上面的图像实际上都是 PNG——在每种情况下,左侧的星星代表栅格图像,右侧的星星代表矢量图像。再次提醒,前往 vector-versus-raster.html 演示查看真实示例!
此外,矢量图像文件比其栅格对应文件轻得多,因为它们只需要存储少量算法,而不是图像中每个像素的单独信息。
什么是 SVG?
SVG 是一种基于 XML 的语言,用于描述矢量图像。它基本上是标记,就像 HTML 一样,只不过您有许多不同的元素来定义您希望在图像中出现的形状以及您希望应用于这些形状的效果。SVG 用于标记图形,而不是内容。SVG 定义了用于创建基本形状的元素,例如 <circle> 和 <rect>,以及用于创建更复杂形状的元素,例如 <path> 和 <polygon>。更高级的 SVG 功能包括 <feColorMatrix>(使用变换矩阵变换颜色)、<animate>(动画化矢量图形的部分)和 <mask>(在图像顶部应用蒙版)。
作为一个基本示例,以下代码创建了一个圆形和一个矩形:
<svg
version="1.1"
baseProfile="full"
width="300"
height="200"
xmlns="https://w3org.cn/2000/svg">
<rect width="100%" height="100%" fill="black" />
<circle cx="150" cy="100" r="90" fill="blue" />
</svg>
这将产生以下输出:
从上面的示例中,您可能会觉得 SVG 很容易手动编码。是的,您可以在文本编辑器中手动编写简单的 SVG,但对于复杂的图像,这很快就会变得非常困难。要创建 SVG 图像,大多数人使用矢量图形编辑器,例如 Inkscape 或 Illustrator。这些软件包允许您使用各种图形工具创建各种插图,并创建照片的近似值(例如 Inkscape 的跟踪位图功能)。
SVG 除了前面描述的优点之外,还有一些额外的优点:
- 矢量图像中的文本保持可访问性(这也对您的 SEO 有益)。
- SVG 非常适合样式/脚本,因为图像的每个组件都是一个可以通过 CSS 样式化或通过 JavaScript 脚本化的元素。
那么为什么有人会选择栅格图形而不是 SVG 呢?嗯,SVG 确实有一些缺点:
- SVG 会很快变得复杂,这意味着文件大小会增加;复杂的 SVG 也可能在浏览器中占用大量处理时间。
- 根据您尝试创建的图像类型,SVG 可能比栅格图像更难创建。
由于上述原因,栅格图形无疑更适合照片等复杂的精确图像。
从 Inkscape 等编辑器导出的 SVG 图形有很大的尺寸优化空间。在将它们部署到 Web 之前,您可能需要通过 SVG 优化器(例如 SVGO)对其进行处理。
向您的页面添加 SVG
在本节中,我们将介绍将 SVG 矢量图形添加到网页的不同方法。
快速方法:img 元素
要通过 <img> 元素嵌入 SVG,您只需在 src 属性中引用它,正如您所期望的那样。您需要一个 height 或 width 属性(如果您的 SVG 没有固有 宽高比,则两者都需要)。如果您尚未阅读,请阅读 HTML 图像。
<img
src="equilateral.svg"
alt="triangle with all three sides equal"
height="87"
width="100" />
优点
- 快速、熟悉的图像语法,在
alt属性中提供了内置的文本等效项。 - 您可以通过将
<img>嵌套在<a>元素中轻松地将图像变成超链接。 - SVG 文件可以被浏览器缓存,从而加快未来使用该图像的任何页面的加载时间。
缺点
- 您无法使用 JavaScript 操作图像。
- 如果您想使用 CSS 控制 SVG 内容,则必须在 SVG 代码中包含内联 CSS 样式。(从 SVG 文件调用的外部样式表无效。)
- 您无法使用 CSS 伪类(例如
:focus)重新设置图像样式。
故障排除和跨浏览器支持
对于不支持 SVG 的浏览器(IE 8 及以下版本,Android 2.3 及以下版本),您可以从 src 属性引用 PNG 或 JPG,并使用 srcset 属性(只有最新的浏览器才识别)来引用 SVG。在这种情况下,只有支持的浏览器才会加载 SVG——较旧的浏览器将加载 PNG:
<img
src="equilateral.png"
alt="triangle with equal sides"
srcset="equilateral.svg" />
您还可以将 SVG 用作 CSS 背景图像,如下所示。在下面的代码中,较旧的浏览器将坚持使用它们理解的 PNG,而较新的浏览器将加载 SVG:
background: url("fallback.png") no-repeat center;
background-image: url("image.svg");
background-size: contain;
与上面描述的 <img> 方法一样,使用 CSS 背景图像插入 SVG 意味着 SVG 无法用 JavaScript 操作,并且也受到相同的 CSS 限制。
如果您的 SVG 完全不显示,那可能是因为您的服务器没有正确设置。如果这是问题所在,这篇文章会为您指明正确的方向。
如何在 HTML 中包含 SVG 代码
您还可以在文本编辑器中打开 SVG 文件,复制 SVG 代码,然后将其粘贴到 HTML 文档中——这有时被称为内联 SVG。确保您的 SVG 代码片段以 <svg> 开始标签开头,并以 </svg> 结束标签结尾。这是一个非常简单的示例,说明您可能会粘贴到文档中的内容:
<svg width="300" height="200">
<rect width="100%" height="100%" fill="green" />
</svg>
优点
- 内联 SVG 可以节省 HTTP 请求,因此可以稍微减少加载时间。
- 您可以为 SVG 元素分配
class和id,并使用 CSS 对它们进行样式设置,无论是在 SVG 内部还是在放置 HTML 文档的 CSS 样式规则的任何位置。实际上,您可以将任何 SVG 呈现属性 用作 CSS 属性。 - 内联 SVG 是唯一一种允许您在 SVG 图像上使用 CSS 交互(例如
:focus)和 CSS 动画(甚至在您的常规样式表中)的方法。 - 您可以通过将 SVG 标记包装在
<a>元素中来将其变成超链接。
缺点
- 此方法仅适用于您只在一处使用 SVG 的情况。重复使用会导致维护资源密集。
- 额外的 SVG 代码会增加 HTML 文件的大小。
- 浏览器无法像缓存常规图像资源那样缓存内联 SVG,因此包含该图像的页面在首次加载后不会加载得更快。
- 您可以在
<foreignObject>元素中包含回退,但支持 SVG 的浏览器仍然会下载任何回退图像。您需要权衡额外的开销是否真的值得,仅仅是为了支持过时的浏览器。
如何使用 iframe 嵌入 SVG
您可以像网页一样在浏览器中打开 SVG 图像。因此,使用 <iframe> 嵌入 SVG 文档就像我们学习 从 <object> 到 <iframe> — 通用嵌入技术 时一样。
以下是一个快速回顾:
<iframe src="triangle.svg" width="500" height="500" sandbox>
<img src="triangle.png" alt="Triangle with three unequal sides" />
</iframe>
这绝对不是最佳选择:
缺点
iframe确实有一个回退机制,如您所见,但浏览器只有在完全不支持iframe时才会显示回退。- 此外,除非 SVG 和您当前的网页具有相同的 源,否则您无法在主网页上使用 JavaScript 操作 SVG。
玩转 SVG
在这个练习中,我们希望您尝试使用一些 SVG。按下播放按钮以在 MDN Playground 中打开下一个示例并进行编辑。
前往 SVG 元素参考,查看您可以使用的其他元素,这些元素提供了许多内置功能。您可以尝试其他形状,例如椭圆,或者您可以尝试使用 图案,甚至是 滤镜效果。本节旨在考察您的研究技能,尝试新事物,并从中获得乐趣。
如果您遇到困难并且无法让代码正常工作,您可以使用 Playground 中的“重置”按钮随时重置它。
<svg width="100%" height="100%">
<rect width="100%" height="100%" fill="red" />
<circle cx="100%" cy="100%" r="150" fill="blue" stroke="black" />
<polygon points="120,0 240,225 0,225" fill="green" />
<text
x="50"
y="100"
font-family="Verdana"
font-size="55"
fill="white"
stroke="black"
stroke-width="2">
Hello!
</text>
</svg>
总结
本文为您提供了关于什么是矢量图形和 SVG、为什么它们有用以及如何将 SVG 包含在网页中的快速介绍。它无意成为学习 SVG 的完整指南,只是一个提示,让您在 Web 旅程中遇到 SVG 时知道它是什么。所以如果您觉得自己还不是 SVG 专家,请不要担心。我们下方提供了一些链接,如果您想了解更多关于其工作原理的信息,这些链接可能会对您有所帮助。
另见
- MDN 上的 SVG 教程
- Sara Soueidan 关于响应式 SVG 图像的教程
- SVG 属性和 CSS
- 如何缩放 SVG(不像栅格图形那么简单!)