我们由 icon-font 转向 SVG 的10 个理由


发布者 andrewleeson  发布时间 1395383018000
关键字 心得体会 

注* 在之前的 在手机上,Data-url和CSS Sprites哪一个更快 一文中,我们介绍过“在手机上,基于Base64的Data URI比比链接图片慢6倍”,在手机端的另一个现象是字体图标(icon font)的广泛使用,此文比较了图标的两种实现方法,很明显作者倾向SVG。


在lonelyplanet.com这个网站上我们使用了大量的图标,最近我们刚完成将图标由icon font替换成SVG文件的工作。我想给大家分享一下我们将图标由icon font替换成目前还存在一定局限性的SVG的理由和我们完成这项工作的经历。

1.关注点分散

我们使用的是自定义字体且过去我们通常将图标放在同一个文件中,将字形存放在一个私有的Unicode区域内。这样做很好,因为这意味着用户在获取图标的时候能少一次HTTP请求,但同时这也让我们觉得在考虑资源加载优先级的时候缺少灵活性。

我们考虑到对于用户体验来说,有一部分图标是至关重要的;但对于字体或者另一部分图标我们并不这样认为。我们试着做以前方法不能完成的事情——在页面内容加载完之后再加载那些不太重要的资源。

将重要的图标从字体中分离出来,那么剩下那些不太重要的图标将允许我们以更精细的方式展现给用户。

反对意见:
没必要将字体和字体图标绑定在一起,你可以提供两种不同的字体。
如果我们坚持font-face(客户端字体)解决方案,我们很可能已经搞定这事了。

2.有些硬件不兼容私有unicode区域

我曾听传闻说在私有unicode区域中硬件比字形更重要,且能用硬件支持emoji表情符号,但直到最近我才见过,以前我从未真正见过。Emoji表情符号曾经是存储在私有unicode区域的,但并不是存放在同一位置;所以这似乎能说明这里面存在的冲突。

我已记不清我曾经是用什么硬件来测试的,但我能记清一个彩色打印机取代了我们的蜱虫图标。那页面看起来显得太糟糕和业余了,但这无疑给我们改变这境况的动力。

3.Opera Mini浏览器上的Font Awesom渲染图

字体支持和检测是在历史上是非常棘手的事情。我敢肯定你一定在Opera Mini浏览器上见过这张Font Awesome的渲染图:


我不会在这个难题上反复琢磨,因为Opera Mini浏览器支持这个功能,且通过aelig一篇文章也得知其它很多平台也能很好的支持。

撇开Opera Mini浏览器不说,我认为最重要的是这将一个我们无法控制的盲点给突显出来了。通过我们自身是无法在所有硬件上进行测试的,所以有意思的技术测试更能说明问题。

平常我们都没有在Opera Mini浏览器上获取大量的流量,但我们作为旅游公司为各种情况、各种带宽的用户提供服务时例外。所以我们想要得做更好,为用户提供更好的服务。用SVG和PNG图片让我们更有自信,因为用户不会再看到混乱糟糕的页面了。

4.最近Chrome浏览器的font-icons支持变得很糟糕

Chrome浏览器的Canary和Beta版本近期遇到一个很严重的字体漏洞的打击。如果你还没有注意到这个漏洞的话,那会发生这样的情况:当页面失去响应一段时间后字体将会被卸载,同时还原为一个系统自带的字体。

当一个字体被卸载后,剩下的内容将会以文本的形式展现,对于Georgia来说这让人感到有点厌烦;尽管页面仍然能用。如果以同样的字体来替代被卸载的字体,那么页面看起来会很糟糕,上面全是一些杂乱的黑框框。

在我们将font-icons替换成SVG的过程中这个漏洞被人们发现了。对于我们来说这无疑是一个很大的救济,因为当时我们正在做第一份关于这的漏洞报告。

反对意见:
这个漏洞在Chrome上并不经常出现

5.火狐浏览器上的Crisper图标

我们发现我们的图标在火狐浏览器上的渲染比在其它浏览器上的渲染要更重些。对于文本来说还好(虽然不是太好),但对于图标来说这会让整个页面显得不好看且笨重。通过使用SVG图标,我们能跨浏览器将页面正常的形态和感觉展示给用户。

6.没必要总是使用内容生成

如果你想要在你的css中使用font-icons,你需要用内容生成的content参数来定义他们。你会发现有时候你必须要写一些复杂的代码才能实现它。因为你已经用:before和:after伪元素或者元素不支持内容生成。

既然那样,你可以选择使用内联渲染,但你会以在大型应用中很容易丢失或被忘记的已标记html实体的分散而结束。

使用SVG图标可以解决这个问题,你可以不受约束的生成内容且能在任何元素上以背景图片的方式渲染它们。

7.对位置的要求没有那么高

当然,这可能取决于我们如何创建和管理图标字形,但我们发现它经常不能在确切需要的位置上出现(也不能跨浏览器展示相同的样式)。我们通过修改行高和使用绝对/相对定位来调整它正确的位置,但很难想出一种能统一调整的方法。

使用SVG能让图标定位变得简单,通过使用background-size(只需覆盖和调整元素的大小)方法来保证在不同浏览器上显示的效果一样。

8.彩色图标

众所周知,font-icons有色彩单一的缺陷。而SVG图标却能支持多色彩、渐变以及其它的一些图形化功能。

在地图上我们通常必须要使用彩色图标,以前我们是在font-icons图标旁使用额外的雪碧图来实现的。使用SVG图标后,我们可以将雪碧图全部删除。对用户来说这能减少一次请求,对我们来说这能减少一些资源维护工作。

反对意见:
用图标分层的方法同样可以实现彩色图标。
即使是这样,但把这事做好意味着我们要面临更大的挑战:如果跨浏览器定位一个图标比较棘手,那么定位多个图标也不会太容易

9.SVG允许我们我们的图标使用动画

虽然我们还没有用过这个功能,但由于这次由font-icons到SVG的转变,下一步我们会逐步考虑应用这个功能的。

10.它总感觉像一个黑客

通过上述的问题,使用font-icons图标总感觉像一个黑客。毋庸置疑,它是一个出色的黑客,但他仍然是一个披着羊皮的狼,获取人们的好感。

Font-face有什么好处呢?

Font-face在某些方面的优势确实强于SVG,因此在做图标替换时我们需要慎重考虑。Font-face最大的优势在于浏览器的广泛支持和颜色的随意替换。

毫不夸张的说,如果没有filamentgroupGrunticon上的贡献,处理这些问题是相当困难的。

颜色的变化

使用图标字体最大的好处就是它的灵活性。你可以很轻松的在任意状态(鼠标悬停、焦点集中、活动中)下随意更换它的颜色。这是一个少见的好功能,同时对于快速开发来说非常有用。这也是我们我们长时间没有下定决心做图标替换的原因。

我们的解决方案

尽管说现在的方案都有各自的缺点,但真正能提供这个功能的方案少之又少。最终我们想出了一个非常令我们开心的解决方案(能严格遵守灵活性和资源大小之间界限的方案)。

Grunticon旨在单独定义每一个图标,从而避免使用雪碧图标。我们一直在用这个方法,但尽管我们为每一个图标准备了一个CSS选择器,我们还是得为每个图标提供如下所示的六种颜色。


由于我们在同一文件中将相同的图标复制多份,在存储的时候能将占用的空间降至一个图标的大小(加上gzip格式文件占用的资源)。这意味着,我们几乎能以零成本使用各种颜色的图标。jsFiddle上给我们演示了如何使用这个方法。

通过这个方案,我们获得了以前认为再也找不回的灵活性。移除全面灵活性应用的同时也额外给我们带来了调色板的跨浏览器增强(在font-icons的应用产品上已经逐步消失的一些东西)。

通过这项技术,我们可以使用更新背景位置的方法,很容易就能实现基于状态图标改变。

很有必要提一下,将来我们可能会将所有的雪碧图标移除,用SVG片段标识符来改变颜色。

浏览器的支持

Font-icons能反过来支持IE8,但SVG不行。为了我们图标替换工作的实现,我们仍然需要浏览器支持background-size,即使这看起来就像是SVG支持。

我们的解决方案

Grunticon创造性地解决了浏览器支持上的遗留问题。它能根据浏览器支持SVG的情况自动的生成不同版本的PNG图片展现给用户。

由于浏览器缺乏对background-size的支持,在老版本浏览器上我们决定只提供一部分图标给用户(一些重要的图标,如LOGO)。通过改变原始SVG图标的大小,有些CSS属性可能会受到限制,但鉴于很多图标都有不同大小的版本,我们还是倾向于只提供给用户以雪碧图标修饰过的稳定图标。  

我们也尝试过用background-size polyfill,但很快就放弃了。如果有超过一个或两个的图标需要改变大小,那么这种方法是极不推荐的。我们发现如果超过两个图标的话IE8浏览器会崩溃不断。

这值得吗?

两种方法都能独立的,可扩展的、轻量级的解决问题。所以不管你选择哪种方法,对于用户来说这都是不错的。总的来说,我们觉得在如何将应用展示给每一个用户和最终额外元素的控制方面,SVG能给我们更多的信心。

自2013年11月开始,SVG就一直应用在Lonely Planet这个网站上,且到目前为止均运行得很好。







回复 (1)
微信扫码 立即评论