有多种使用图标的方法,但是最好的解决方案始终包括SVG,无论是嵌入式实现还是链接为图像文件。这是因为它们是在代码中“绘制”的,从而使其在任何上下文中都具有灵活性,适应性和可伸缩性。
但是,在使用SVG时,总是有机会包含很多不必要的代码。在某些情况下,内联SVG的代码可能会很长,从而使文档的滚动时间更长,使用起来不舒服,是的,它比需要的要重一些。
我们可以解决这个代码重用块与<use>
元素或适用本地变量来管理我们的SVG风格从一个地方。或者,如果我们在服务器端环境中工作,我们总是可以撒一些PHP(或类似的东西)来提取SVG文件的内容,而不是直接将其放入。
很好,但是如果我们可以在文件级别解决此问题,而不是采用基于代码的方法,那将不是很好吗?我想关注一个不同的角度:如何使用基本形状以更少的代码制作相同的图形。这样,我们在不牺牲质量或外观变化的情况下,在项目中获得了更小,可控制和语义的图标的好处。我将通过不同的示例来探讨常用图标的代码,以及如何使用我们可以制作的一些最简单的SVG形状重绘它们。
这是我们将要处理的图标:
让我们看一下可以用来使代码保持简洁的基本形状。
s! 这是我在holasvg.com上创建的简单图标的更长列表!在本文之后,您将知道如何修改它们并使它们成为您自己的。
使用<line>
元素简化关闭图标
这是从flaticon.com下载并由pixel-perfect构建的“关闭”或“十字”图标的代码:
在此示例中,一切都发生在<path>
data属性(d
)中,其中包含许多命令和参数。SVG正在做的是从边界追踪形状。
如果您熟悉Illustrator,这相当于绘制两条单独的线,将它们转换为形状,然后将它们与路径查找器组合在一起以创建一个复合形状。
该<path>
元素允许我们绘制复杂的形状,但是在这种情况下,我们可以用两条线创建相同的图形,同时保持相同的外观:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50" width="50" height="50" overflow="visible" stroke="black" stroke-width="10" stroke-linecap="round">
<line x1="0" y1="0" x2="50" y2="50" />
<line x1="50" y1="0" x2="0" y2="50" />
</svg>
我们首先定义一个viewBox
从0,0到50,50的a。您可以选择自己喜欢的尺寸;SVG始终可以很好地缩放到您定义的任何宽度和高度。为了使事情变得容易,在这种情况下,我还定义了50个单位的内联宽度和高度,这避免了图形中的额外计算。
要使用该<line>
元素,我们声明线的第一个点的坐标和线的最后一个点的坐标。在这种情况下,我们从开始于x=0 y=0
到结束x=50 y=50
。
这就是代码中的样子:
<line x1="0" y1="0" x2="50" y2="50" />
第二行将从以下处开始x=50 y=0
并结束x=0 y=50
:
<line x1="50" y1="0" x2="0" y2="50" />
SVG笔划默认情况下没有颜色,这就是我们black
在stroke
属性上添加值的原因。我们还为该stroke-width
属性设置了10个单位的宽度,并为其指定了stroke-linecap
一个round
值以复制原始设计的那些圆角。这些属性被直接添加到<svg>
标签中,因此这两行都将继承它们。
<svg ... stroke="black" stroke-width="10" stroke-linecap="round" ...>
现在,笔划比其默认大小(1个单位)大10个单位,该行可能会被裁剪viewBox
。我们可以将点在内移动10个单位viewBox
或添加overflow=visible
到样式中。
可以删除等于0的值,因为默认值为0。这意味着这两行最后只有两行非常小的代码:
<line x2="50" y2="50" />
<line x1="50" y2="50" />
仅仅通过将a更改<path>
为a <line>
,我们不仅制作了一个较小的SVG文件,而且制作了一个更具语义性和可控制性的代码块,从而使以后的维护变得更加容易。视觉效果与原始效果完全相同。
相同的十字架,不同的代码。
使用<circle>
和<path
>元素简化时钟图标
我以Barracuda从The Noun Project创建的时钟图标为例:
这个形状也是用绘制的<path>
,但是我们还有很多名称空间和XML指令,它们与所使用的软件和文件的许可证有关,我们可以在不影响SVG的情况下删除它们。您能告诉我们使用什么插图编辑器来创建图标吗?
让我们使用一个圆圈和一条路径通过更简单的命令从头开始重新创建此代码。同样,我们需要viewBox
从0 开始,从0到100,100,并且宽度和高度与这些单位匹配。
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" width="100" height="100" fill="none" stroke="black" stroke-width="10" stroke-linecap="round" stroke-linejoin="round">
<circle cx="50" cy="50" r="40"/>
<path d="M50 25V50 H75" />
</svg>
我们与<svg>
标签中的上一个图标保持相同的样式。fill
是black
默认设置,因此我们需要明确为其赋予一个none
值以将其删除。否则,该圆将具有黑色实心填充,遮盖其他形状。
要绘制,<circle>
我们需要指定半径所在位置的中心点。我们可以用cx
(中心x)和cy
(中心y)来实现。然后,r
(半径)将声明我们的圆的大小。在此示例中,半径略小于viewBox
,因此当笔划为10个单位宽时不会被裁剪。
这些字母怎么了?查看Chris Coyier的插图指南,以获取有关SVG语法的入门知识。
我们可以使用a <path>
作为指针,因为它有一些非常有用且简单的命令可以绘制。在d
(数据)内部,我们必须从M
(移至)命令开始,然后是从我们开始绘制的坐标,在此示例中为50,25(在圆的顶部中心附近)。
在V
(垂直)命令之后,我们只需要一个值,因为我们只能以负数或正数向上或向下移动。正数将下降。相同的H
(水平),后跟一个正数75,它将向右绘制。所有命令都是大写的,因此我们选择的数字将是网格中的点。如果我们决定使用小写字母(相对命令),则数字将是我们在一个方向上移动的单位数量,而不是坐标系中的绝对点。
相同的时钟,不同的代码。
使用<rect>
和<polyline>
元素简化信封图标
我在Illustrator中绘制了信封图标,而没有扩展原始形状。这是来自导出的代码:
Illustrator提供了一些SVG选项来导出图形。我在“ CSS属性”下拉列表中选择了“样式元素”,因此我可以使用一个<style>
标签,其中包含一些可能要移至CSS文件的类。但是,当然有多种方法可以在SVG中应用样式。
这段代码中已经有了基本形状!我没有在Illustrator中选择“形状到路径”选项,这对那里很有帮助。我们可以使用SVGOMG进一步优化此功能,以删除注释,XML指令和不必要的数据,例如空元素。如果需要,我们可以从那里手动删除其他功能。
我们已经有了一些简洁的东西:
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" x="0" y="0" viewBox="0 0 310 190" xml:space="preserve">
<style>.st0{fill:none;stroke:#000;stroke-width:10;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10}
</style><rect x="5" y="5" class="st0" width="300" height="180"/>
<polyline class="st0" points="5 5 155 110 305 5"/>
</svg>
我们可以移除更多东西而不会影响信封的外观,包括:
version="1.1"
(自SVG 2 开始不推荐使用)id="Layer_1"
(这没有任何意义或用途)x="0"
(这是默认值)y="0"
(这是默认值)xml:space="preserve"
(自SVG 2 开始不推荐使用)
<svg xmlns="http://www.w3.org/2000/svg" x="0" y="0" viewBox="0 0 310 190">
<style>.st0{fill:none;stroke:#000;stroke-width:10;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10}
</style>
<rect x="5" y="5" class="st0" width="300" height="180"/>
<polyline class="st0" points="5 5 155 110 305 5"/>
</svg>
如果我们真的想变得更具侵略性,可以将CSS样式移到单独的样式表中。
<rect>
需要一个起点,我们将从该起点开始扩展宽度和高度,因此让我们使用 x="5"
,y="5"
这是我们的左上角。从那里,我们将创建一个宽度为300个单位,高度为180个单位的矩形。就像时钟图标一样,我们将以5,5为起点,因为我们有一个10单位的笔划,如果坐标位于0,0将会被裁剪。
<polyline>
与相似<line>
,但是我们在points属性内定义了无数的点,就像坐标对一样,一个接一个,一个对,第一个数字代表x
,第二个 数字代表y
。用逗号读取序列更容易,但是可以将它们替换为空格,而不会影响结果。
相同的信封,不同的代码。
奖励形状!
我没有提供可以用<polygon>
和<ellipse>
形状简化的图标的示例,但这是一种使用它们的快速方法。
<polygon>
与相同<polyline>
,仅此元素将始终定义闭合形状。这是直接来自MDN的示例:
还记得我们之前为时钟图标绘制的圆圈吗?r
用rx
和替换(半径)ry
。现在,您有两个不同的半径值。这是MDN的另一个示例:
包起来
我们在很短的时间内覆盖了很多地方!虽然我们使用示例来演示优化SVG的过程,但我希望您能从本文中摆脱出来:
- 请记住,压缩始于在插图软件中绘制SVG的方式。
- 使用可用的工具(如SVOMG)压缩SVG。
- 如有必要,请手动删除不必要的元数据。
- 用基本形状替换复杂的路径。
<use
>是“内联” SVG以及建立自己的可重用图标库的好方法。
通过组合这些基本形状可以创建多少个图标?
我正在holasvg.com/icons上列出我的列表,我将在这里不断上传更多的图标和功能,现在您知道如何通过更改一些数字轻松地对其进行修改。来吧,让他们成为你的!