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

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

最近有人问我如何调试内联 SVG。 因为它是 DOM 的一部分,所以我们可以在任何浏览器 DevTools 中检查任何内联 SVG。 正因为如此,我们有能力确定范围并发现任何潜在问题或优化 SVG 的机会。

但有时,我们甚至根本看不到我们的 SVG。 在这些情况下,我在调试时会寻找六个特定的东西。

1. viewBox 价值观

viewBox 在使用 SVG 时,这是一个常见的混淆点。 在没有它的情况下使用内联 SVG 在技术上很好,但我们会失去它最重要的好处之一:使用容器进行缩放。 同时,如果配置不当,它可能会对我们不利,导致不必要的削波。

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

在 Illustrator 中的艺术作品区域之外的猫线艺术和绘图的一部分。
在 Illustrator 中打开的 SVG 屏幕截图。

解决这个问题的最简单方法? 添加 overflow="visible" 到 SVG,无论是在我们的样式表中,还是在 style 属性或直接作为 SVG 表示属性。 但是如果我们也应用一个 background-color 到 SVG 或者如果我们在它周围有其他元素,事情可能看起来有点不对劲。 在这种情况下,最好的选择是编辑 viewBox 显示隐藏的坐标系部分:

演示应用 overflow="hidden" 并编辑视图框。

还有一些关于 viewBox 在我们讨论这个话题时值得一提的是:

怎么样 viewBox 工作?

SVG 是一个无限大的画布,但我们可以通过视口和 viewBox.

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

viewBox 由四个值定义。 前两个是左上角的起点(xy 值,允许负数)。 我正在编辑这些以重新构图。 最后两个是视口内坐标系的宽度和高度——这是我们可以编辑网格比例的地方(我们将在 缩放).

这是显示 SVG 的简化标记 viewBoxwidthheight 属性都设置在 <svg>:

<svg viewBox="0 0 700 700" width="700" height="700"> <!-- etc. -->
</svg>

重新构架

所以这:

<svg viewBox="0 0 700 700">

…映射到这个:

<svg viewBox="start-x-axis start-y-axis width height">

我们看到的视口从哪里开始 0 在 x 轴和 0 在 y 轴上相遇。

通过改变这个:

<svg viewBox="0 0 700 700">

……对此:

<svg viewBox="300 200 700 700">

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

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

缩放

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

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

下面的图 1 显示了一个蓝点 900 沿 x 轴和 900 沿 y 轴。 如果我改变最后两个 viewBox 值来自 700900 喜欢这个:

<svg viewBox="300 200 900 900" width="700" height="700">

…然后蓝点几乎完全回到视野中,如下面的图 2 所示。 因为我们增加了 viewBox 的值,所以我们的图像被缩小了,但是 SVG 的实际宽度和高度尺寸保持不变,并且蓝点回到更靠近未剪切区域的地方。

图1。
图1
6 个常见的 SVG 失败(以及如何修复它们)PlatoBlockchain 数据智能。 垂直搜索。 人工智能。
图2

有一个粉红色的方块作为网格如何缩放以适应视口的证据:单位变得更小,更多的网格线适合相同的视口区域。 您可以在以下 Pen 中使用相同的值来查看实际效果:

2.遗失 widthheight

调试内联 SVG 时我经常看的另一件事是标记是否包含 width or height 属性。 在许多情况下这没什么大不了的,除非 SVG 位于具有绝对定位的容器或灵活的容器内(因为 Safari 计算 SVG width 价值与 0px 而不是 auto). 排除 width or height 在这些情况下,我们无法看到完整的图像,正如我们可以看到的那样 打开这个 CodePen 演示 并在 Chrome、Safari 和 Firefox 中进行比较(点击图片可查看大图)。

6 个常见的 SVG 失败(以及如何修复它们)PlatoBlockchain 数据智能。 垂直搜索。 人工智能。
6 个常见的 SVG 失败(以及如何修复它们)PlatoBlockchain 数据智能。 垂直搜索。 人工智能。
Safari
6 个常见的 SVG 失败(以及如何修复它们)PlatoBlockchain 数据智能。 垂直搜索。 人工智能。
火狐

解决方案? 添加宽度或高度,无论是作为表示属性、内联样式属性还是在 CSS 中。 避免单独使用高度,尤其是当它设置为 100% or auto. 另一种解决方法是 设置正确  左值.

你可以玩 下面的笔 并组合不同的选项。

3.不慎 fillstroke 颜色

也可能是我们正在给 <svg> 标记,无论它是内联样式还是来自 CSS。 这很好,但是整个标记或样式中可能有其他颜色值与 <svg>,导致零件不可见。

这就是为什么我倾向于寻找 fillstroke SVG 标记中的属性并将其擦除。 以下视频显示了我在 CSS 中使用红色样式设置的 SVG fill. 在几个实例中,我删除的标记中直接用白色填充了部分 SVG 以显示缺失的部分。

4. 遗失身份证

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

这是做事的好方法。 但是有很多次我看到同一个 SVG 文件被第二次导出到同一个位置并且 ID 不同,通常是在直接复制/粘贴矢量时。 可能添加了一个新图层,或者对现有图层中的一个进行了重命名等等。 不管怎样,CSS 规则不再与 SVG 标记中的 ID 匹配,导致 SVG 的呈现方式与您预期的不同。

元素 ID 后带数字的下划线
将 Illustrator 导出的 SVG 文件粘贴到 SVGOMG 中。

在大型 SVG 文件中,我们可能会发现很难找到这些 ID。 现在是打开 DevTools、检查图形中不起作用的部分并查看这些 ID 是否仍然匹配的好时机。

所以,我认为值得在代码编辑器中打开一个导出的 SVG 文件,并在交换之前将其与原始文件进行比较。 Illustrator、Figma 和 Sketch 等应用程序很智能,但这并不意味着我们不负责审查它们。

5. 裁剪和遮罩清单

如果 SVG 被意外裁剪并且 viewBox 检查出来,我通常会查看 CSS clip-path or mask 可能会干扰图像的属性。 继续查看内联标记很诱人,但最好记住 SVG 的样式可能发生在其他地方。

CSS 裁剪和遮罩 允许我们“隐藏”图像或元素的一部分。 在 SVG 中, <clipPath> 是一种矢量操作,它可以切割图像的各个部分而不会产生中间结果。 这 <mask> 标签是一种像素操作,允许透明、半透明效果和模糊边缘。

这是一个用于调试涉及裁剪和遮罩的案例的小清单:

  • 确保剪切路径(或蒙版)和图形相互重叠。 重叠部分是显示的内容。
  • 如果您有不与图形相交的复杂路径,请尝试应用变换直到它们匹配。
  • 您仍然可以使用 DevTools 检查内部代码,即使 <clipPath> or <mask> 没有渲染,所以使用它!
  • 复制里面的标记 <clipPath><mask> 并在关闭之前粘贴 </svg> 标签。 然后添加一个 fill 到那些形状并检查 SVG 的坐标和尺寸。 如果您仍然看不到图像,请尝试添加 overflow="hidden"<svg> 标签。
  • 检查一个 独特 ID用于 <clipPath> or <mask>,并且相同的 ID 应用于被剪裁或遮罩的形状或形状组。 不匹配的 ID 会破坏外观。
  • 检查标记之间的拼写错误 <clipPath> or <mask> 标签。
  • fill, stroke, opacity, 或应用于内部元素的一些其他样式 <clipPath> 没有用——唯一有用的部分是这些元素的填充区域几何形状。 这就是为什么如果你使用 <polyline> 它会表现为 <polygon> 如果你使用 <line> 你不会看到任何剪裁效果。
  • 如果您在应用后没有看到您的图像 <mask>,请确保 fill 的掩蔽内容并不完全是黑色的。 遮蔽元素的亮度决定了最终图形的不透明度。 您将能够看穿较亮的部分,而较暗的部分将隐藏图像的内容。

您可以在 这支笔.

6.命名空间

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

<svg xmlns="http://www.w3.org/2000/svg"> <!-- etc. -->
</svg>

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

SVG 2 规范 不需要命名空间 使用 HTML 语法时。 但 这很关键 如果对遗留浏览器的支持是优先考虑的——另外,添加它也没有什么坏处。 这样,当 <html> 元素的 xmlns 属性已定义,在极少数情况下不会发生冲突。

<html lang="en" xmlns="http://www.w3.org/1999/xhtml"> <body> <svg xmlns="http://www.w3.org/2000/svg" width="700px" height="700px"> <!-- etc. --> </svg> </body>
</html>

在 CSS 中使用内联 SVG 时也是如此,比如将其设置为背景图像。 在以下示例中,验证成功后输入上会出现一个复选标记图标。 这就是 CSS 的样子:

textarea:valid { background: white url('data:image/svg+xml, <svg xmlns="http://www.w3.org/2000/svg" width="26" height="26"> <circle cx="13" cy="13" r="13" fill="%23abedd8"/> <path fill="none" stroke="white" stroke-width="2" d="M5 15.2l5 5 10-12"/> </svg>') no-repeat 98% 5px;
}

当我们在 background 属性中删除 SVG 内部的命名空间时,图像消失了:

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

提升您的 SVG 技能!

如果您发现自己正在对渲染不当的内联 SVG 进行故障排除,我希望这些技巧可以帮助您节省大量时间。 这些正是我寻找的东西。 也许您有不同的危险信号要注意——如果是这样,请在评论中告诉我!

最重要的是,至少对以下内容有基本的了解是值得的 SVG 的各种使用方式. CodePen 挑战 经常合并 SVG 并提供良好的实践。 这里还有一些资源可以升级:

对于 SVG 相关的优点,我建议关注一些人:

时间戳记:

更多来自 CSS技巧