最近有人问我如何调试内联 SVG。因为它属于 DOM 的一部分,所以我们可以在任何浏览器的 DevTools 中检查任何内联 SVG。正因如此,我们能够对事情进行范围界定,并发现任何潜在问题或 SVG 优化的机会。
但有时,我们甚至根本看不到我们的 SVG。在这些情况下,调试时我会寻找六个特定方面。
在使用 SVG 时,viewBox 是一个常见的混淆点。从技术上讲,在没有 viewBox 的情况下使用内联 SVG 也没问题,但我们会失去其最重要的优势之一:随容器缩放。同时,如果配置不当,它可能会对我们不利,导致出现意外裁剪。
当元素被裁剪时,它们就在那里——它们只是在我们看不到的坐标系的一部分中。如果我们在某些图形编辑程序中打开该文件,它可能看起来像这样:
最简单的解决方法是什么?向 SVG 添加 overflow="visible"
,无论是在样式表中、内联样式属性中,还是直接作为 SVG 表示属性。但是,如果我们还向 SVG 应用背景颜色,或者周围有其他元素,事情可能看起来有点不对劲。在这种情况下,最佳选择是编辑 viewBox 以显示隐藏的坐标系部分:
关于 viewBox,还有一些额外的事情值得在讨论时介绍:
SVG 是一个无限画布,但我们可以通过视口和 viewBox 来控制我们看到的内容以及如何看到它。
视口是无限画布上的窗口框架。其尺寸由 width
和 height
属性定义,或在 CSS 中使用相应的 width
和 height
属性定义。我们可以指定任何我们想要的长度单位,但如果我们提供无单位的数字,它们默认为像素。
viewBox 由四个值定义。前两个是左上角的起点(x 和 y 值,允许负数)。我正在编辑这些以重新构图。后两个是视口中坐标系的宽度和高度——在这里我们可以编辑网格的比例(我们将在缩放部分讨论)。
以下是显示在 <svg></svg>
上同时设置了 SVG viewBox 和 width
和 height
属性的简化标记:
<svg height="700" viewbox="0 0 700 700" width="700"></svg>
所以,这个:
<svg viewbox="0 0 700 700"></svg>
……映射到这个:
<svg viewbox="start-x-axis start-y-axis width height"></svg>
我们看到的视口始于 x 轴上的 0 和 y 轴上的 0 相交的地方。
通过更改此内容:
<svg viewbox="0 0 700 700"></svg>
……到这个:
<svg viewbox="300 200 700 700"></svg>
……宽度和高度保持不变(每个 700 个单位),但坐标系的起点现在位于 x 轴上的 300 点和 y 轴上的 200 点。
在下面的视频中,我向 SVG 添加了一个红色 <circle></circle>
,其中心位于 x 轴上的 300 点和 y 轴上的 200 点。请注意,将 viewBox 坐标更改为相同的值也会将圆的放置位置更改为框架的左上角,而 SVG 的渲染大小保持不变(700×700)。我所做的只是用 viewBox“重新构图”。
我们可以更改 viewBox 内的后两个值以放大或缩小图像。值越大,添加到视口中的 SVG 单位就越多,从而导致图像变小。如果我们想保持 1:1 的比例,我们的 viewBox 宽度和高度必须与我们的视口宽度和高度值匹配。
让我们看看在 Illustrator 中更改这些参数时会发生什么。画板是视口,由一个 700 像素的白色正方形表示。该区域之外的所有内容都是我们无限的 SVG 画布,默认情况下会被裁剪。
下面的图 1 显示了一个蓝色点,位于 x 轴上的 900 和 y 轴上的 900。如果我将后两个 viewBox 值从 700 更改为 900,如下所示:
<svg height="700" viewbox="0 0 700 700" width="700"></svg>
……那么蓝色点几乎完全回到了视野中,如下面的图 2 所示。我们的图像缩小了,因为我们增加了 viewBox 值,但 SVG 的实际宽度和高度尺寸保持不变,并且蓝色点回到了更靠近未裁剪区域的位置。
有一个粉红色正方形作为网格如何缩放以适应视口的证据:单位变小,并且更多网格线适合相同的视口区域。您可以在下面的 Pen 中使用相同的值来查看其工作原理:
调试内联 SVG 时,我查看的另一个常见问题是标记中是否包含 width
或 height
属性。在许多情况下,这没什么大不了的,除非 SVG 位于具有绝对定位或灵活容器的容器内(因为 Safari 使用 0px 而不是 auto 计算 SVG 宽度值)。在这些情况下,排除宽度或高度会阻止我们看到完整的图像,正如我们通过打开此 CodePen 演示并在 Chrome、Safari 和 Firefox 中进行比较所看到的那样(点击图像可查看更大的视图)。
解决方案?添加宽度或高度,无论是作为表示属性、内联样式属性还是在 CSS 中。避免单独使用高度,尤其是在将其设置为 100%
或 auto
时。另一种解决方法是设置 right
和 left
值。
您可以使用以下 Pen 并组合不同的选项进行尝试。
也可能是我们正在向 <svg></svg>
标签应用颜色,无论是内联样式还是来自 CSS。这很好,但标记或样式中可能还有其他颜色值与 <svg></svg>
上设置的颜色冲突,导致部分内容不可见。
这就是为什么我倾向于在 SVG 的标记中查找 fill
和 stroke
属性并将其删除的原因。以下视频显示了一个我在 CSS 中使用红色填充进行样式设置的 SVG。在 SVG 中,有一些地方的填充直接在标记中以白色填充,我将其删除以显示缺失的部分。
这个看起来可能非常明显,但你会惊讶地发现我看到它出现的频率有多高。假设我们在 Illustrator 中制作了一个 SVG 文件,并且非常努力地命名图层,以便在导出文件时获得不错的匹配 ID。假设我们计划通过连接到这些 ID 来在 CSS 中设置该 SVG 的样式。
这是一种不错的做法。但是,有很多次我看到相同的 SVG 文件第二次导出到相同的位置,并且 ID 不同,通常是在直接复制/粘贴矢量时。也许添加了一个新图层,或者重命名了现有图层之一,或者其他什么。无论如何,CSS 规则不再与 SVG 标记中的 ID 匹配,导致 SVG 的渲染方式与预期不同。
在大型 SVG 文件中,我们可能难以找到这些 ID。这是一个打开 DevTools、检查不起作用的图形部分并查看这些 ID 是否仍然匹配的好时机。
因此,我会说在交换内容之前,打开代码编辑器中的导出 SVG 文件并将其与原始文件进行比较是值得的。像 Illustrator、Figma 和 Sketch 这样的应用程序很智能,但这并不意味着我们没有责任审核它们。
如果 SVG 被意外裁剪并且 viewBox 检查正常,我通常会查看 CSS 中可能干扰图像的 clip-path
或 mask
属性。查看内联标记很诱人,但最好记住 SVG 的样式可能发生在其他地方。
CSS 裁剪和蒙版允许我们“隐藏”图像或元素的部分。在 SVG 中,<clippath></clippath>
是一个矢量操作,它会裁剪图像的部分,没有中间结果。<mask></mask>
标签是一个像素操作,允许透明度、半透明效果和模糊边缘。
这是一个用于调试涉及裁剪和蒙版的情况的小型检查清单:
<clippath></clippath>
或 <mask></mask>
未渲染,您仍然可以使用 DevTools 检查内部代码,因此请使用它!<clippath></clippath>
和 <mask></mask>
内的标记,然后将其粘贴在关闭标签之前。然后向这些形状添加填充并检查 SVG 的坐标和尺寸。如果您仍然没有看到图像,请尝试向 <svg></svg>
标签添加 overflow="hidden"
。<clippath></clippath>
或 <mask></mask>
使用了唯一的 ID,以及是否将相同的 ID 应用于被裁剪或蒙版的形状或形状组。不匹配的 ID 会破坏外观。<clippath></clippath>
或 <mask></mask>
标签之间的标记中是否有错别字。<clippath></clippath>
内元素的 fill
、stroke
、opacity
或其他一些样式是无用的——唯一有用的部分是这些元素的填充区域几何形状。这就是为什么如果您使用 <polyline></polyline>
,它会表现得像 <polygon></polygon>
,而如果您使用 <line></line>
,您将看不到任何裁剪效果。<mask></mask>
后没有看到图像,请确保蒙版内容的填充不是完全黑色。蒙版元素的亮度决定最终图形的不透明度。您将能够透过较亮的部分看到,而较暗的部分会隐藏图像的内容。您可以在此 Pen 中使用蒙版和裁剪元素进行练习。
您知道 SVG 是一种基于 XML 的标记语言吗?是的,它是!SVG 的命名空间设置在 xmlns
属性上:
<svg height="700" viewbox="0 0 700 700" width="700"></svg>
关于 XML 中的命名空间有很多需要了解的内容,MDN 上有一个很好的入门介绍。可以这么说,命名空间为浏览器提供上下文,告知它标记特定于 SVG。其思想是,当同一个文件中有多种类型的 XML 时(例如 SVG 和 XHTML),命名空间有助于防止冲突。这在现代浏览器中是一个不太常见的问题,但可以帮助解释旧版浏览器或像 Gecko 这样的浏览器在定义文档类型和命名空间时严格的 SVG 渲染问题。
SVG 2 规范在使用 HTML 语法时不需要命名空间。但如果支持旧版浏览器是一个优先事项,那么这一点至关重要——此外,添加它也不会造成任何损害。这样,当定义元素的 xmlns
属性时,在那些罕见的情况下就不会发生冲突。
<svg height="700" viewbox="0 0 700 700" width="700"></svg>
在使用内联 SVG 在 CSS 中时(例如将其设置为背景图像)也是如此。在下面的示例中,成功验证后,复选标记图标会出现在输入框中。CSS 的外观如下所示:
<svg viewbox="0 0 700 700"></svg>
当我们在背景属性中删除 SVG 内的命名空间时,图像会消失:
另一个常见的命名空间前缀是 xlink:href
。当引用 SVG 的其他部分时,我们经常使用它,例如:图案、滤镜、动画或渐变。建议开始将其替换为 href
,因为另一个自 SVG 2 以来已被弃用,但可能与旧版浏览器存在兼容性问题。在这种情况下,我们可以同时使用两者。请记住,如果您仍在使用 xlink:href
,请包含命名空间 xmlns:xlink="http://www.w3.org/1999/xlink"
。
如果您发现自己正在对渲染不正确的内联 SVG 进行故障排除,我希望这些技巧可以帮助您节省大量时间。这些只是我寻找的东西。也许您有不同的危险信号需要关注——如果有,请在评论中告诉我!
最重要的是,至少对 SVG 的各种使用方法有基本的了解是值得的。CodePen Challenges 经常包含 SVG 并提供良好的实践。以下是一些提升水平的更多资源:
我建议关注一些与 SVG 相关的优秀人士:
以上是6常见的SVG失败(以及如何修复它们)的详细内容。更多信息请关注PHP中文网其他相关文章!