SVG:定义、关键概念及在Web开发中的使用

作者: IT Sectr 发布日期: 2026-06-12 阅读时间: 10 分钟

SVG — 是一种基于XML的矢量图像格式,由W3C联盟开发。与JPEG和PNG等光栅格式不同,SVG存储形状的数学描述:线条、曲线、圆形和文本。这使得图像可以缩放到任何尺寸而不会损失质量。根据MDN Web Docs, 2025,所有现代浏览器都支持SVG,并将其用于图标、插图、动画和图表。在Web开发中,SVG凭借其小尺寸和通过CSS进行样式化的能力,已成为自适应界面的标准。

要点

  • SVG — 基于XML的可缩放矢量图形,在任何放大倍数下都不会损失质量。
  • SVG元素:rect、circle、ellipse、line、polyline、polygon、path和text — 以数学方式描述形状。
  • fill和stroke属性 设置填充和描边颜色,从父元素继承。
  • 内联SVG 允许通过CSS对元素进行样式化并通过JavaScript直接进行管理。
  • viewBox 定义SVG的坐标系,并确保独立于容器尺寸的自适应缩放。

什么是SVG?

SVG — 是一种基于XML的矢量图形格式,于2001年作为W3C推荐标准出现。与光栅格式不同,SVG通过几何基元来描述图像:点、线、曲线和多边形。SVG文件是一个普通的文本XML文档,可以使用标准工具进行读取、编辑和压缩。

SVG的架构包括几个关键概念。viewBox 定义一个虚拟坐标系,独立于元素的实际尺寸。例如,viewBox="0 0 100 100" 创建一个100×100的方形网格,其中的所有坐标都是固定的。当容器的宽度或高度发生变化时,内容会按比例缩放。

根据W3C SVG 2规范,现代版本的SVG支持渐变、遮罩、滤镜、任意定位的文本、通过JavaScript的交互性以及通过CSS和SMIL的动画。SVG作为完整的HTML元素集成到DOM中,允许以编程方式管理每个图形基元。

在移动开发中,SVG也通过iOS中的UIGraphicsImageRenderer和Android中的VectorDrawable使用 — 两种格式都将类似SVG的描述转换为GPU上硬件加速的光栅。

SVG格式的历史和发展

SVG 1.0于2001年成为W3C推荐标准,SVG 1.1于2003年,SVG 2.0自2012年起一直在开发中。SVG 2的主要创新是与CSS更深入的集成、对合成和混合模式的支持,以及在HTML中无需namespace前缀即可使用SVG的可能性。

尽管SVG 2尚未达到推荐标准状态,但现代浏览器已经支持其大部分功能。Chrome、Safari、Firefox和Edge几乎完全支持SVG 1.1,并支持SVG 2的很大一部分。

SVG的基本元素

SVG提供了一组元素来描述二维图形。每个元素都有决定其位置、大小和视觉外观的属性。属性可以指定为XML属性或通过CSS属性。

  • <rect> — 矩形,具有x、y、width、height、rx、ry属性(圆角)。
  • <circle> — 圆形,具有cx、cy(圆心)和r(半径)属性。
  • <ellipse> — 椭圆,具有cx、cy、rx、ry属性。
  • <line> — 线段,具有x1、y1、x2、y2属性。
  • <polyline> — 折线,具有points属性(坐标列表)。
  • <polygon> — 封闭多边形,具有points属性。
  • <path> — 任意轮廓,具有d属性(命令:M、L、C、Q、A、Z)。
  • <text> — 文本元素,具有x、y、font-size、font-family属性。

path元素 — 最强大和最灵活的SVG元素。d属性包含一系列命令:M(移动到)、L(画线到)、C(三次贝塞尔曲线)、Q(二次贝塞尔曲线)、A(弧线)、Z(闭合路径)。每个命令都有绝对形式或相对形式(大写或小写字母)。

SVG还支持通过<g>对元素进行分组。组将其视觉属性(fill、stroke、transform)继承给所有子元素。这允许将统一样式应用于整个形状集合并通过单个transform管理其位置。

SVG与光栅图形:格式比较

SVG与光栅格式(JPEG、PNG、WebP)之间的主要区别 — 信息存储的方式。光栅将每个像素的颜色存储在固定大小的网格中。SVG存储用于再现形状的数学命令。这种区别决定了格式的所有优点和缺点。

特性SVG光栅(PNG/JPEG)
缩放无质量损失放大时质量损失
文件大小对于简单形状很小取决于分辨率
编辑文本方式,通过代码需要图形编辑器
CSS样式化完全支持
动画CSS + SMIL仅GIF或APNG
照片不适合理想
图标/标志理想多余
浏览器支持96%+100%

根据HTTP Archive, 2025,68%的网站使用SVG作为图标,34%用于插图,22%用于标志。SVG图标的平均大小为0.5–2 KB,而类似质量的光栅图标在PNG格式中为5–20 KB。

对于照片和复杂的光栅图像,SVG不适合 — XML描述的尺寸将超过等效JPEG的尺寸。建议的SVG应用领域:图标、标志、插图、示意图、图表、具有自适应设计的界面元素。

何时选择SVG以及何时选择光栅格式

SVG — 适用于界面元素的最佳选择,这些元素需要在Retina屏幕和任何浏览器缩放比例下保持清晰。光栅 — 适用于照片、复杂纹理和具有数百万颜色的图像,其中矢量描述将不必要地复杂。

混合方法 — 将SVG用于界面元素和WebP/AVIF用于照片内容相结合 — 在质量和页面加载性能之间提供了最佳平衡。

内联SVG和通过CSS进行样式化

内联SVG — 是将SVG标记直接嵌入到HTML文档中,而不是作为通过<img>或background-image的单独文件。内联SVG的优点在于SVG元素成为DOM的一部分,并且可以通过CSS进行样式化、通过JavaScript进行管理以及无需额外的服务器请求即可进行动画。

与SVG被隔离在shadow DOM中的<img src="icon.svg">不同,内联SVG继承父文档的颜色和字体。例如,这允许通过CSS伪类:hover在悬停时更改图标的颜色,而无需为每个状态加载单独的文件。

根据CSS-Tricks,内联SVG是在现代Web应用程序中使用图标的首选方法。CSS属性fill、stroke、stroke-width直接应用于SVG元素。要通过CSS进行自定义,重要的是在原始SVG中fill和stroke没有设置为内联属性 — 否则CSS无法覆盖它们。

  • 优点:通过CSS样式化、通过JS管理、无HTTP请求、viewBox适应性。
  • 缺点:HTML页面大小增加、无法单独于HTML进行缓存。
  • 替代方案:SVG精灵 — 将多个SVG合并到一个文件中并使用<use href="#id">。

SVG精灵解决了缓存问题:所有图标收集在一个文件中,浏览器加载一次,各个图标通过<use>并引用精灵内所需元素的id进行连接。

SVG动画:CSS和SMIL

CSS SVG动画 — 在浏览器中对矢量图形进行动画的最常见和最有效的方法。诸如transform、opacity和fill等CSS属性应用于SVG元素的方式与应用于HTML元素的方式相同。对于沿任意路径的动画,使用CSS属性offset-path。

SMIL(同步多媒体集成语言) — SVG中内置的动画机制,独立于CSS。<animate>、<animateTransform>和<animateMotion>元素允许在无需JavaScript和CSS的情况下对任何SVG属性进行动画。SMIL动画保证与浏览器的帧率同步。

根据MDN Web Docs,所有现代浏览器都支持SMIL,但CSS动画被认为是更可预测和更有效的。SMIL的主要场景 — 对无法通过CSS访问的属性进行动画,例如<path>元素的d(路径)属性。

JavaScript + requestAnimationFrame 提供对SVG动画的最大控制。Web开发人员使用GSAP和Anime.js库来处理复杂的动画序列,这些序列带有时间轴和缓动函数,难以通过纯CSS实现。

代码示例:创建SVG图形

第一个示例 — 使用基本SVG元素的简单房子图标。所有形状都是rect和polyline:

html
<!-- Inline SVG icon -->
<svg viewBox="0 0 100 100" width="48" height="48" xmlns="http://www.w3.org/2000/svg">
  <rect x="20" y="50" width="60" height="40" fill="#4A90D9" />
  <rect x="35" y="65" width="30" height="25" fill="#fff" />
  <polyline points="10,50 50,15 90,50" fill="none" stroke="#4A90D9" stroke-width="6" />
</svg>

第二个示例 — 通过CSS实现加载器的旋转动画。使用带有stroke-dasharray属性的<circle>来创建虚线轮廓:

html
<!-- CSS animated spinner -->
<svg class="spinner" viewBox="0 0 50 50" width="40" height="40">
  <circle cx="25" cy="25" r="20" fill="none"
    stroke="#4A90D9" stroke-width="4"
    stroke-dasharray="125.6 31.4" />
</svg>

<style>
  .spinner circle {
    animation: spin 1.5s linear infinite;
    transform-origin: center;
  }
  @keyframes spin {
    to { transform: rotate(360deg); }
  }
</style>

第三个示例 — 通过GSAP库实现路径动画,用于平滑绘制轮廓。GSAP使用stroke-dashoffset属性,产生线条出现的效果:

js
// 使用GSAP绘制路径
import gsap from "gsap";

const path = document.querySelector("#myPath");
const length = path.getTotalLength();

gsap.set(path, {
    strokeDasharray: length,
    strokeDashoffset: length
});

gsap.to(path, {
    strokeDashoffset: 0,
    duration: 2,
    ease: "power2.out"
});

常见问题

用简单的话说什么是SVG?

SVG 是一种图像格式,它存储的不是像素,而是数学形状:线条、圆形、矩形和曲线。因此,SVG图像可以放大到任何尺寸 — 仍会保持清晰。SVG文件是文本XML代码,可以在任何代码编辑器中进行编辑。

对于图标,SVG在哪些方面比PNG更好?

SVG占用更少的空间(0.5–2 KB,而PNG为5–20 KB),在Retina屏幕上不会损失质量,支持动画和通过CSS进行样式化。对于界面图标,SVG是标准。PNG更适合照片和具有复杂颜色过渡的图像。

如何在悬停时更改SVG的颜色?

在标记中使用不带fill属性的内联SVG,然后在CSS中设置fill:svg:hover path { fill: red; }。如果SVG是通过<img>连接的,则无法通过CSS更改颜色 — 请使用内联SVG或带有<use href="#id">的SVG精灵。

什么是viewBox在SVG中?

viewBox 是SVG的虚拟坐标系,独立于元素的实际尺寸。格式:viewBox="minX minY width height"。例如,viewBox="0 0 100 100"创建一个100×100的坐标网格。所有内部坐标都相对于此网格定义,并在容器大小更改时自动缩放。

可以在没有JavaScript的情况下动画化SVG吗?

是的。SVG支持CSS动画(关键帧、过渡)和SMIL — 一种内置动画机制,包含<animate>、<animateTransform>和<animateMotion>元素。SMIL允许对无法通过CSS访问的属性进行动画,例如<path>元素的路径属性。

总结

  • SVG — 基于XML的矢量格式,可缩放而不损失质量,并受所有现代浏览器支持。
  • 基本元素:rect、circle、ellipse、line、polyline、polygon、path和text — 涵盖二维图形的所有任务。
  • SVG在图标、标志和界面元素的文件大小和Retina质量方面优于光栅格式。
  • 内联SVG 集成到DOM中,并允许通过CSS对元素进行样式化、通过JavaScript进行管理和动画。
  • viewBox确保SVG的适应性 — 内容自动适应容器的大小。
  • SVG动画可以通过CSS(过渡、关键帧)、SMIL(<animate>)和JavaScript(GSAP、Anime.js)实现。
  • SVG精灵将多个图标合并到一个文件中,以实现高效缓存和加速加载。

我们将开发一款交钥匙移动应用程序

IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。

讨论项目

另请阅读