6 个常见的 SVG 错误(以及如何修复它们)

发布:admin2026-06-13 10:52:43 6384条浏览分类:世界杯日本爆冷

最近有人问我如何处理内联 SVG 的调试。因为它属于 DOM 的一部分,所以我们可以在任何浏览器的 DevTools 中检查任何内联 SVG。因此,我们能够对事物进行范围界定,并发现任何潜在问题或优化 SVG 的机会。

但有时,我们根本无法看到我们的 SVG。在这些情况下,在进行调试时,我会寻找六个特定方面。

1. viewBox 值

在使用 SVG 时,viewBox 是一个常见的混淆点。从技术上讲,在没有它的情况下使用内联 SVG 也没问题,但我们会失去它最重要的优势之一:随容器缩放。同时,如果配置不当,它可能会对我们不利,导致出现不需要的裁剪。

当元素被裁剪时,它们仍然存在——只是在我们看不到的坐标系的一部分中。如果我们在某些图形编辑程序中打开该文件,它可能看起来像这样

在 Illustrator 中打开的 SVG 的屏幕截图。

最简单的解决方法是什么?在 SVG 中添加 overflow="visible",无论是在我们的样式表中、内联在 style 属性中还是直接作为 SVG 表示属性。但是,如果我们还将 background-color 应用于 SVG 或周围有其他元素,则外观可能会略有偏差。在这种情况下,最佳选择是编辑 viewBox 以显示隐藏的坐标系部分。

演示应用 overflow="hidden" 和编辑 viewBox。

在讨论 viewBox 的同时,还有一些其他值得关注的事项。

viewBox 是如何工作的?

SVG 是一个无限画布,但我们可以通过视口和 viewBox 控制我们看到的内容以及如何看到它。

视口是在无限画布上的一个窗口框架。它的尺寸由 width 和 height 属性定义,或者在 CSS 中使用相应的 width 和 height 属性定义。我们可以指定任何我们想要的长度单位,但如果我们提供无单位的数字,则默认为像素。

viewBox 由四个值定义。前两个是左上角的起始点(x 和 y 值,允许使用负数)。我正在编辑这些值以重新构图。后两个是视口中坐标系的宽度和高度——在这里我们可以编辑网格的比例(我们将在关于缩放的部分中详细介绍)。

以下简化的标记显示了 SVG viewBox 和在 上同时设置的 width 和 height 属性

重新构图

所以,这

…映射到这

我们看到的视口从 x 轴上的 0 和 y 轴上的 0 相交处开始。

通过更改这

…到这

…宽度和高度保持不变(每个 700 个单位),但坐标系的起点现在位于 x 轴上的 300 点和 y 轴上的 200 点。

在下面的视频中,我向 SVG 添加了一个红色的 ,其中心位于 x 轴上的 300 点和 y 轴上的 200 点。请注意,将 viewBox 坐标更改为相同的值也会将圆圈的位置更改到框架的左上角,而 SVG 的渲染大小保持不变(700×700)。我所做的只是使用 viewBox “重新构图”。

缩放

我们可以更改 viewBox 内的后两个值以放大或缩小图像。值越大,要适应视口的 SVG 单位就越多,从而导致图像变小。如果我们想要保持 1:1 的比例,则我们的 viewBox 宽度和高度必须与我们的视口宽度和高度值匹配。

让我们看看在 Illustrator 中更改这些参数时会发生什么。画板是 viewport,由一个白色的 700px 正方形表示。该区域之外的所有内容都是我们的无限 SVG 画布,默认情况下会被裁剪。

下面的图 1 显示了一个蓝色点,它位于 x 轴上的 900 和 y 轴上的 900。如果我将后两个 viewBox 值从 700 更改为 900,如下所示

…那么蓝色点几乎完全回到了视野中,如下面的图 2 所示。我们的图像已缩小,因为我们增加了 viewBox 值,但 SVG 的实际宽度和高度尺寸保持不变,并且蓝色点回到了更靠近未裁剪区域的位置。

图 1

图 2

有一个粉红色的正方形作为网格如何缩放以适应视口的证据:单位变小,并且更多网格线适合相同的视口区域。您可以在以下 Pen 中使用相同的值来查看其工作原理。

2. 缺少 width 和 height

在调试内联 SVG 时,我还会查看的另一个常见问题是标记中是否包含 width 或 height 属性。在许多情况下,这没什么大不了的,除非 SVG 位于具有绝对定位或弹性容器的容器内(因为 Safari 使用 0px 而不是 auto 计算 SVG width 值)。在这些情况下,排除 width 或 height 会阻止我们看到完整的图像,正如我们可以通过打开此 CodePen 演示并在 Chrome、Safari 和 Firefox 中进行比较(点击图像以查看更大的视图)看到的那样。

Chrome

Safari

Firefox

解决方案?添加宽度或高度,无论是作为表示属性、内联在 style 属性中还是在 CSS 中。避免单独使用高度,尤其是在将其设置为 100% 或 auto 时。另一种解决方法是设置 right 和 left 值。

您可以使用以下 Pen并结合不同的选项。

3. 无意中的 fill 和 stroke 颜色

也可能是我们正在将颜色应用于 标签,无论是内联样式还是来自 CSS。这很好,但标记或样式中可能还有其他与 上设置的颜色冲突的颜色值,导致部分内容不可见。

因此,我倾向于在 SVG 的标记中查找 fill 和 stroke 属性并将其删除。以下视频显示了一个我在 CSS 中使用红色 fill 进行样式化的 SVG。在几个地方,SVG 的部分直接在标记中以白色填充,我将其删除以显示缺失的部分。

4. 缺少 ID

这可能看起来非常明显,但你会惊讶地发现我经常看到它出现。假设我们在 Illustrator 中制作了一个 SVG 文件,并且非常仔细地命名了图层,以便在导出文件时获得很好的匹配 ID。并且假设我们计划通过挂钩到这些 ID 在 CSS 中为该 SVG 设置样式。

这是一种很好的处理方式。但是,我见过很多次将同一个 SVG 文件第二次导出到同一个位置,而 ID 却不同,通常是在直接复制/粘贴矢量时发生这种情况。也许添加了一个新图层,或者其中一个现有图层被重命名了,或者其他什么原因。无论如何,CSS 规则不再与 SVG 标记中的 ID 匹配,导致 SVG 的渲染效果与预期不同。

将 Illustrator 导出的 SVG 文件粘贴到 SVGOMG 中。

在大型 SVG 文件中,我们可能很难找到这些 ID。此时,打开 DevTools,检查图形中不正常的部分,看看这些 ID 是否仍然匹配是一个好方法。

因此,我建议在交换任何内容之前,在代码编辑器中打开导出的 SVG 文件,并将其与原始文件进行比较。像 Illustrator、Figma 和 Sketch 这样的应用程序很智能,但这并不意味着我们不需要对它们进行审查。

5. 修剪和蒙版的检查清单

如果 SVG 被意外修剪,并且 viewBox 检查结果正常,我通常会查看 CSS 中是否存在可能干扰图像的 clip-path 或 mask 属性。查看内联标记很容易让人分心,但要记住,SVG 的样式可能在其他地方设置。

CSS 修剪和蒙版 允许我们“隐藏”图像或元素的部分内容。在 SVG 中, 是一种矢量操作,可以剪切图像的部分内容,没有中间结果。 标签是一种像素操作,允许透明度、半透明效果和模糊边缘。

这是一个用于调试涉及修剪和蒙版情况的小型检查清单

确保修剪路径(或蒙版)和图形相互重叠。重叠的部分是显示的部分。

如果有一个复杂的路径没有与您的图形相交,请尝试应用转换,直到它们匹配。

即使 没有渲染,您仍然可以使用 DevTools 检查内部代码,所以请使用它!

复制 内部的标记,并将其粘贴到 标签之前。然后为这些形状添加一个 fill,并检查 SVG 的坐标和尺寸。如果仍然看不到图像,请尝试向 标签添加 overflow="hidden"。

检查是否为 使用了**唯一的** ID,以及是否将相同的 ID 应用于被修剪或蒙版的形状或形状组。不匹配的 ID 将破坏外观。

检查 标签之间的标记中是否存在错别字。

fill、stroke、opacity 或应用于 内元素的其他样式都是无用的——唯一有用的部分是这些元素的填充区域几何形状。这就是为什么如果使用 ,它将表现为 ,而如果使用 ,则不会看到任何修剪效果。

如果在应用 后看不到图像,请确保蒙版内容的 fill 不是纯黑色。蒙版元素的亮度决定了最终图形的不透明度。您将能够透过较亮的部分看到,而较暗的部分将隐藏图像的内容。

您可以在这个 Pen中体验蒙版和修剪元素。

6. 命名空间

您知道 SVG 是一种基于 XML 的标记语言吗?是的,它是!SVG 的命名空间设置在 xmlns 属性上。

关于 XML 中的命名空间有很多需要了解的,MDN 对此有一个很好的入门介绍。简单来说,命名空间为浏览器提供上下文,告知它该标记特定于 SVG。其思想是,当同一个文件中存在多种类型的 XML(如 SVG 和 XHTML)时,命名空间有助于防止冲突。这在现代浏览器中是一个不太常见的问题,但可能有助于解释旧版浏览器或像 Gecko 这样在定义文档类型和命名空间时非常严格的浏览器中出现的 SVG 渲染问题。

SVG 2 规范不要求在使用 HTML 语法时使用命名空间。但是至关重要如果支持旧版浏览器是优先事项——此外,添加它也没有任何坏处。这样,当 元素的 xmlns 属性被定义时,它在那些罕见的情况下就不会发生冲突。

这在 CSS 中使用内联 SVG 时也适用,例如将其设置为背景图像。在下面的示例中,在成功验证后,输入框后面会出现一个复选标记图标。CSS 看起来是这样的

textarea:valid {

background: white url('data:image/svg+xml,\

\

\

\

') no-repeat 98% 5px;

}

当我们删除 background 属性中 SVG 内部的命名空间时,图像就会消失。

另一个常见的命名空间前缀是 xlink:href。当引用 SVG 的其他部分(如:图案、滤镜、动画或渐变)时,我们经常使用它。建议开始将其替换为 href,因为另一个自 SVG 2 以来已被弃用,但可能会与旧版浏览器存在兼容性问题。在这种情况下,我们可以同时使用两者。如果您仍在使用 xlink:href,请记住包含命名空间 xmlns:xlink="https://w3org.cn/1999/xlink"。

提升你的 SVG 技能!

我希望这些技巧能帮助您节省大量时间,如果您发现自己正在排查渲染不正确的内联 SVG。这些只是我寻找的东西。也许您有不同的危险信号需要关注——如果有,请在评论中告诉我!

最重要的是,至少要对SVG 的各种使用方法有一个基本的了解。 CodePen Challenges 经常包含 SVG 并提供良好的练习。以下是一些提升技能的资源

使用 SVG 与 CSS3 和 HTML5(Amelia Bellamy-Royds、Kurt Cagle、Dudley Storey)——我认为它是 SVG 圣经。

Lea Verou 拥有丰富的 SVG 知识,并且多次在主题演讲中谈到它(例如2019 年前端联合大会上的这段视频)。

SVG 动画(Sarah Drasner)

SVG 基础(Amelia Bellamy-Royds、J. David Eisenberg)

实用 SVG(Chris Coyier)

有几个人我建议关注,以获取与 SVG 相关的优质内容

Sara Soueidan

Carl Schoof

Cassie Evans

Val Head

Ana Tudor