基于本文的目的,我会以一个像个人名片的东西来开始。它会简短地介绍一下我自己以及显示3个和我工作相关的网络档案。
从上面的截图你可以看到我使用了三个图标(Twitter,Dribble 和 Github)象征着我的网络档案。这些图标我是从 flaticon 下载到的,这是一个具有各种不同图标和符号的网站,并且每个图标都提供矢量和光栅格式。
PNG 和 SVG
我们会在支持SVG的浏览器中使用SVG的格式,然后在不支持svg的浏览器中使用PNG格式的图标。
通常我使用Sketch来输出我的PNG图标和SVG图标。
简单的SVG实现
在上面的截图中你会注意到我将分组和图形都在左侧面板进行了适当的命名。(Adobe Illustrator在图层面板中有个相似的视图)。将资源正确地命名是很重要的,这不仅仅让它们保持组织性,更是对后面的图标使用有很大帮助。
输出SVG
现在我会将这些图标输出为SVG格式,我们可以用Sketch的slicing工具来轻松地完成这项工作。在Sketch的输出配置选项中你可以得到更多的信息从而明白它是如何工作的。我会将它们输出为单独的文件并放置在我项目中的images目录中。
通常地,你要在网站中展示一张图片你需要通过一个元素的src属性中来指向这个资源,类似下面这样:
然而,对于SVG来说我们可以有几种不同的方法来在HTML文档中使用它们。举个例子,我们可以使用直观的SVG代码来描述一张图片。代码可能会是这样:
twitter-icon
Created with Sketch.
这是我上面输出的其中一个图标,是基于XML的格式的呈现。这些代码几乎就像一段HTML一样,这意味着我们可以插入这段代码到页面中。
在HTML中添加inline SVG
让我们以一个基础的HTML页面开始,里面包含了3个赋予了链接的PNG图标,以及它们的容器:
现在我会开始复制上面SVG图标代码并黏贴到这里面,但我会忽略这段说明文件编码方式和其他信息的代码。因为在HTML文档中已经包含了这部分的信息,我们无需复制进去。
在这个HTML页面中,我已经将SVG放在了PNG图标的正上方。现在我要把PNG图片的代码注释掉防止它再SVG图片后面再出现一次。
清理 SVG
接着我准备清理一下上面的SVG代码。移除掉那些可选的元素属性,因为我要移除的这些属性并不会影响SVG的表现。下面是优化后跟优化前的代码对比,但他们表现效果是一样的:
twitter-icon
Created with Sketch.
注意我移除的那些元素。
, , 和 元素目前是不需要的,但在本文后面我们可能会用到它们。其中代表着分组的元素相当于我在Sketch文档中的分组。默认地Sketch是将所有的东西放在一个页面中的,相当于组元素
这部分的最后一步就是移除掉SVG标签上的height和width属性。它们会在我的CSS文件中来定义,如下所示:
.icon {
max-
max-
transition: .2s;
-webkit-filter: drop-shadow(0 1px 0 #11222d);
}
如果你跟着我的步骤你应该能在浏览器看到一个简洁锐利的矢量图。
提示:你可以通过浏览器的放大缩小来看看这个图片是否为SVG。这个图片不应该会受到你浏览器放大缩小而产生变化。
提供Fallback
如果你使用svg来在客户端显示,你会想它的浏览器支持程度如何,实际上svg可以在除了ie8(和ie8以下的)以及 Opera Mini 以外的所有浏览器上工作。但就目前来说,ie8在全球中只占到了4%的份额,Opera Mini 只有3%的份额。所以你没必要去为他们提供兼容,但尽管如此我还是会给给你一个解决方案。
这是我上面3个图标中的其中一个图标,但你会注意到我的png图标也在里面,只是以注释地形式存在着。这个png图片就是我们的fallback。
干掉注释
首先我会移除掉上面的注释。我需要将 移动到元素里面,放在组元素后面。
然后我会将 包裹在svg特有的元素foreignObject里面。如果浏览器不能识别svg的矢量信息,它会找到“foreign object”并使用它里面的 元素。我们也需要告诉浏览器如果支持矢量图标那就应该把“foreign object”忽略掉。这就是元素存在的目的了,我用它来将元素和元素包裹了起来。
下面是更新后的代码:
如果你跟着我的步伐到这里并写下我上面这段html,你会发现如果你的浏览器不支持svg它就会使用png图片来显示。(但我测试下来,这种方式会导致加载png图片,用注释的方式则不会,所以这并不是一种可取的方案)
创建一个 SVG Sprite
svg sprites几乎跟image sprites一样。就最简单的形式来说,sprites是将几张图合并到一起的一张图片。每一张图都可以通过css 和html来获取,一般通过sprite在一个展现“窗口”的指定的坐标来取到其中的某张图片(超出窗口部分的被截取隐藏掉)。
它最主要的优点就是能减少页面的加载时间,优化开发流程,以及保持页面中图片元素的一致性。其中第二和第三点可以很好地应用在svg sprites中。因为我们可以紧紧在一处地方更新我们的svg而不是让svg的代码块散落在文档的各个地方。
我会在页面的元素的闭合标签前面创建一个新的元素。这个元素将会包含我前面所有的图标。
下一步我要将图标都放到里面去。但我不需要把整个svg代码块都放进去,只要把组元素和它的内容堆叠到头部的元素里就好了。
David Darnes - Web Designer & Front-end Developer
提示:如果你熟悉Grunt的使用,你可以用一个插件来自动的将你所有单独的svg文件合并到一起。
隐藏!
现在我们把所有的图标都放在头部,我们需要把它们隐藏起来。在这个标签中添加一个属性display=”none”就能让所有的图标都不显示在页面的头部了。
定义每一个图标
我们下一步就是去定义每一个图标这样我门才能在页面中重用他们,定义的地方就在我们之前清理svg时删掉的元素里面,通过用它来包裹所有的组元素,就能把所有的图标都放进去,然后在页面任何地方使用了。
David Darnes - Web Designer & Front-end Developer
使用图标
图标我们已经定义好了,但需要一个方法来引用,use 元素就是用来干这个事情的。元素允许我们把元素里面的任意元素取出放到页面的任何地方。我们是通过它的id的来取到它们的,这也是为什么在Sketch文档中命名我们的图标是件很重要的事情。
注意前面例子中元素的id,然后我是这样通过use元素来映射它们的, 。
跟着我的教程到这里,你会发现你的图片没有任何变化,但是你现在可以在任意的位置不限次数地(以任何尺寸)来使用它们。
让你的SVG Sprite更加完美
一个使用svg sprites的优点是你页面上的代码变地更加地简洁并且对于你的项目伙伴来说它的可读性也更加强了。但我们还可以进一步地优化。
下面我把在svg sprite中的元素替换为元素,另外我把viewbox属性从svg元素移动到元素上。
David Darnes - Web Designer & Front-end Developer
使用元素不仅仅更加地语义化,至少在我的例子中,我们还可以避免元素上的viewbox属性的重复出现。另外我们现在还可以把之前移除的title和desc元素放回来,用他们来提高我们图标的可访问性。
David Darnes - Web Designer & Front-end Developer
Dribbble
Dribbble portfolio
GitHub
GitHub account
通过将组元素变为symbol