图标字体 VS 雪碧图——图标字体应用实践
本文介绍使用图标字体和SVG取代雪碧图的方法。雪碧图是很多网站经常用到的一种技术,但是它有缺点:高清屏会模糊、无法动态变化如hover时候反色。而使用图标字体可以完美解决上述问题,同时具备兼容性好,生成的文件小等优点。
雪碧图
雪碧图实例:淘宝PC端

将多张小图放至一张大图
使用的时候,通过background-position调整显示的位置,如下图所示:

雪碧图的使用方法
使用雪碧图唯一的优点,可以说就是减少浏览器的请求次数。因为浏览器同一时间能够加载的资源数是一定的,IE 8是6个,Chrome是6个,Firefox是8个。为了验证,写了以下html结构:(这部份虽然有点跑题,但是很要必要深究一下)

验证Chrome同时加载个数的html--很多张很大的图片
然后在Chrome的开发者工具里面的Timeline可以看到Chrome确实是6个6个加载的,每次最多加载6个:

Chrome同时最多加载资源数为6个
雪碧图的制作方法可以用node的一个的包css-sprite,十分地方便。只要将图标做好,放到相应的文件夹里面,写好配置文件运行,就能够生成相应的图片和css,无需自己手动去调整位置等css属性。详见css-sprite
然而,使用雪碧图存在不可避免的缺点
雪碧图的缺点
高清屏会失真
在2x的设备像素比的屏幕上例如mac,如果要达到和文字一样的清晰度,图片的宽度需要实际显示大小的两倍,否则看起来会比较模糊:读者可以对比左边文字和右边图片里文字的清晰度

右边图片里的文字比左边字体的文字模糊
特别是现在手机绝大部份是高清屏了,例如iphone 6 plus的分辨率达到了1920 * 1080,所以为了高清屏,使用雪碧图可能要准备多种规格的图片。
雪碧图不方便变化
雪碧图是一张静态的图片,当他生成的那天就注定了他要以什么样的方式展示,因此我不能动态地改变他的颜色,无法让他变大(可能会失真),无法像文字一样加一个阴影效果等等。例如下面的菜单,hover或者选中的时候反色:


选中或者hover时反色
或者是某一天UI要换颜色、某一天老总挂了,为表哀悼,为个公司的网站要换个灰色调。使用雪碧图时,所有的图标都得重新制作。
使用图标字体可以完美解决上面的问题
图标字体icon font
图标字体就是将图标作成一个字体,使用时与普通字体无异,可以设置字号大小、颜色、透明度等等,方便变化,最大优点是拥有字体的矢量无失真特点,同时可以兼容到IE 6。还有一个优点是生成的文件特别小,215个图标的生成的ttf字体文件才41KB

一个图标字体里面的元素
如何制作图标字体
需要准备PS和AI,打开UI图,选中图标的图层,通常它是设计师画的一个形状:


1. 选中图标的图层
然后执行:文件->导出->Illustrator,如下左图所示,将生成一个AI文件。用AI打开刚刚生成的文件,执行File->Scripts->SaveDocsAsSVG,如下右图所示,将生成一个SVG文件:


2. 左: PS里导出AI文件,右:AI里面导出SVG
接下来,借助一个第三方的网站制作图标icomoon.io,进入app页面,选择导入icon,将刚刚生成的svg上传上去

3. 上传到icomoon
最后生成字体并下载:

4. 生成几种规格的字体
使用的时候通过@font-face引入,根据图标的编码就可以在页面中使用了。
然而在实际的操作中并没有像上面说的那么顺利,会遇到很多阻碍,笔者也是摸索了很久才总结了一套实用的经验,这也是其它介绍图标字体的教程没有提及到的,看其它很多教程可能会在实际使用中遇到很多坑。
坑1:图标字体只支持单路径
通常情况下,设计师在制作图标的时候是用多个路径组合出来的,在上面的导出的svg也是带有多个路径的,打开svg文件就可以知道,它是由几个path组成的:

导出的svg文件是由几个path组成的
但是字体只支持单路径, 一个解决办法是手办修改svg文件,把多个path合并成一个,这就要求对svg格式比较熟悉。但是这种方法吃力不讨好,只适用比较简单的情况,复杂的图标最后合并的效果很难做到和原先的一模一样。
有一个比较智能的办法,就是使用PS的合并形状组件的功能:

使用PS合并形状组件
这样子生成的svg就是单路径的,有时候会遇到“合并形状组件”的菜单项是置灰的,只要把图层的小眼睛点掉再打开就可以了(或者可能本身就是单路径的)。
坑2:有些图标是多个图层组成的
一开始不知道,所以比较笨的方法是分别生成几个svg之后,再去手动去合并svg。其实PS有一个合并形状的功能,选中多个形状后,右键“合并形状”:

使用PS合并多个形状图层
坑3:生成的SVG填充可能被置为none
有时候会遇到生成了svg,但是上传上去是空的,检查一下svg文件发现是fill被置为none了,如下所示:

生成的svg是fill:none
这个时候需要手动改一下svg文件,把fill:none改成随便一个色值即可,如fill:#000000.
使用一个脚本自动导出svg
在上面的操作中,都是要先执行PS导出再到AI里面执行导出,其实有一个脚本,能够自动执行这两步:PSD to SVG, 支持PS CS6,不支持CC,还可以把这个脚本设置一个快捷方式,用起来非常方便。使用这个脚本需要注意的是图层的命名不能带中文,不然会出错,所以通常把图层复制到一个新的文件里面进行操作。

使用PSD to SVG增加便利
现在重点说下,图标字体的使用和一些注意事项
图标字体的使用
通过font-face导入自定义字体,可以参考字体下载后的demo。然后,把所有使用图标字体的span/a标签都加一个.icon的类,.icon类设置font-family为font-face定义的字体名
@font-face {
font-family: 'icon-font';
src: url('fonts/icon-font.eot');
src: url('fonts/icon-font.eot#iefix') format('embedded-opentype'),
url('fonts/icon-font.ttf') format('truetype'),
url('fonts/icon-font.woff') format('woff'),
url('fonts/icon-font.svg#icon-font') format('svg');
font-weight: normal;
font-style: normal;
} .icon{
font-family: "icon-font":
}
最后,每个图标使用它在相应的编码或者HTML实体:

图标字体的两种使用方法
其中,e9d3是当前图标在这个字体里面的十六进制编码。在普通字体里,0的编码是0x16,即48,为0的ascii编码。
在使用过程中遇到的坑:
1. webkit浏览器会在加缘加粗1个像素
如下,读者可找下区别:

左边的图标边缘多了一个像素,右边是正常的
这个问题在间距比较小的时候就会比较明显,例如上图第二个图标中间。解决文案是加一个font-smoothing的属性:
.icon{
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
2. 注意缓存
后续加了新的图标字体,如果不做处理的话,已经加载过的浏览器可能会有缓存,导致新的图标字体不会重新下载,所以需要处理这个问题。最简单的就是在上面的@font-face导入的url里面添加一个版本号的参数:
src: url('fonts/icon-font.eot?hadf22');
或者更彻底的:改变文件名、路径名。
3. 多人协作
icomoon免费版的数据是存储在浏览器的本地数据库的, 商业版交点钱可以把数据放在云端,从而实现多人协作。免费版也可以实现多人协作,方法是将别人生成的字体svg导进去再添加,生成新的svg字体,同样别人要再上传的时候先上传这个svg。商业版使用的时候需要注意多人同时操作的情况,有可能会同时生成相同的编码。阿里也提供了一个在线的图标字体制作网站:http://www.iconfot.cn,和icommon相比,没有提供编码的方式只能够使用HTML实体的方式。另外icommon还提供了在线编辑的功能还有大量图标的搜索功能,商业版提供woff2字体下载。
图标字体的缺点
图标字体有一个显而易见的缺点,不支持多色图标。因为它是一个字体,决定了它只能是单色的。如果实再是要使用多色的图标,甚至带一些特殊效果的那就使用SVG吧。
结合使用SVG
对于多色的图标,可以在页面插入一个SVG:

左边的location的图标就是使用了svg,效果比直接贴一张PNG好很多
SVG的兼容性,除了IE 8不支持,其它的都还好。况且现在很多新项目都不再兼容IE 8了,不然连个border-radius都用不了。
有几种使用SVG的方法:
1. 直接copy到页面
例如,后端如果用的是JSP,那么可以借助include功能:
<%@ include file="loc-svg.jsp"%>
loc-svg.jsp里面的内容就是svg:

借助jsp嵌套svg
这样做的缺点是浏览器没办法缓存,同时会阻碍页面的加载。优点是由于是内联的,可以直接用CSS控制svg的样式
2. 使用embed/object
<embed src="loc.svg" width="100" height="200"/>
除此之外,还可以使用img标签,将svg的路径作为src属性,这种方法的缺点是没办法用CSS控制样式。还可以转化为base64的方式。更多使用SVG的方式参见:Using SVG
当小个的SVG过多的时候,可能要考虑把多个小的SVG合并成一个SVG,就像雪碧图那样:
3. 合并SVG
如下所示:通过一个个的symbol,将多个svg合在了一起,同时将每个symbol svg定义一个id,使用的时候会用到
<svg>
<symbol viewBox="0 0 101.5 57.9" id="active-triangle"><path fill="#15c0f1" d="M100.4.5L50.7 57.1 1.1.5h99.3z"/>
<symbol viewBox="0 0 101.5 57.9" id=“logo"><path fill="#15c0f1" d="M120.4.5L50.7 57.1 1.1.5h99.3z"/>
</svg>
使用的时候通过外链的办法将svg引到页面上,如要用到上面定义的logo,通过“文件名#ID”的方式:
<svg viewBox="0 0 100 100">
<use xlink:href=“icon.svg#logo"></use>
</svg>
然而蛋疼的IE不支持外链,但是有人写了个插件,可以让IE支持,原理是检测到浏览器不支持外链的时候就将其外链替换成相应的svg内容,详见svg for everybody
使用SVG的还有highCharts和d3.js等。
至此,整个流程说明完毕~ 图标字体和SVG结合使用,提升网站的高清体验。
个人博客: http://yincheng.site/icon-font
图标字体 VS 雪碧图——图标字体应用实践的更多相关文章
- 把所有的小图标一起做成雪碧图吧 请用gulp-css-spriter.
用gulp-css-spriter很简单. 第一步: 在某个文件夹用shitf+鼠标右键 第二步: npm install gulp-css-spriter https://www.npmjs.com ...
- 多个图标图片(雪碧图)使用CSS样式显示
现在的网页中显示很多图标算是常态,发现项目中页面上用到的图标都是单个图标单个文件,用的时候直接往页面上挂,这确实很常态. 如果,网站是挂在外网上,或者网速过低,又大量使用图标的情况下,由于浏览器和服务 ...
- css雪碧图(精灵图)与字体图标的介绍以及对比
css雪碧图(精灵图)与字体图标的介绍以及对比 设想一个实际场景:在一个页面为了展示,我们放置了很多独立的小图片,浏览器在显示页面的时候,就需要向服务器就会发送很多请求,来获取并加载这些小图片,但是这 ...
- css背景雪碧图等
1.背景图 雪碧图技术 要设置背景,是要设置在某个盒子上 <!doctype html> <html lang="en"> <head> < ...
- 前端-如何用gulp快速搭建项目(sass预编译,代码压缩,css前缀,浏览器自动刷新,雪碧图合成)
一:gulp优点: 易于使用 通过代码优于配置的策略,Gulp 让简单的任务简单,复杂的任务可管理: 插件高质 Gulp 严格的插件指南确保插件如你期望的那样简洁高质得工作. 构建快速 利用 Node ...
- CSS Sprite雪碧图的应用
CSS雪碧图,即CSS Sprite,也有人叫它CSS精灵图,是一种图像拼合技术.该方法是将多个小图标和背景图像合并到一张图片上,然后利用CSS的背景定位来显示需要显示的图片部分. 雪碧图的使用场景 ...
- Vue-cli3.0下的雪碧图插件webpack-spritesmith配置方法
在前端项目中,为了减少对图片的请求次数,一般而言需要进行雪碧图的配置.即将多张小图标合并成一张图片,这样页面中的小图标都在一张图片上,只需请求一张图片,就可以通过CSS设置各个小图标的显示,利于节省带 ...
- !!字体图标(iconfont、Fontello 、雪碧图生成工具。Glyphicons、fontawesome 等)。 图片压缩
http://www.iconfont.cn/ 阿里巴巴矢量图标库 iconfont http://fontawesome.io fontawesome图标 http://www.bootcss.c ...
- 雪碧图和如何实现浏览器中title的小图标
background-position 雪碧图 我们的html和css中有三个属性可以向服务器发送请求 ser href url 2.overflow (1) 值hidden 超出就隐藏 (2)值sc ...
随机推荐
- Electron使用与学习--(基本使用与菜单操作)
对于electron是个新手,下面纯属个人理解.如有错误,欢迎指出. 一.安装 如果你本地按照github上的 # Install the `electron` command globally ...
- angular2系列教程(九)Jsonp、URLSearchParams、中断选择数据流
大家好,今天我们要讲的是http模块的第二部分,主要学习ng2中Jsonp.URLSearchParams.observable中断选择数据流的用法. 例子
- 算法与数据结构(十七) 基数排序(Swift 3.0版)
前面几篇博客我们已经陆陆续续的为大家介绍了7种排序方式,今天博客的主题依然与排序算法相关.今天这篇博客就来聊聊基数排序,基数排序算法是不稳定的排序算法,在排序数字较小的情况下,基数排序算法的效率还是比 ...
- 掌握javascript中的最基础数据结构-----数组
这是一篇<数据结构与算法javascript描述>的读书笔记.主要梳理了关于数组的知识.部分内容及源码来自原作. 书中第一章介绍了如何配置javascript运行环境:javascript ...
- 基于fis3的组件可视化道路
首先说明一下,即使不熟悉fis3,阅读文本应该也会有所收获. 本文以fis-parser-imweb-tplv2插件为模板插件,目的不在于使用哪个模板,而是组件可视化的实现思路,不必担心. 先说说模板 ...
- LINQ to SQL Where条件
1. 适用场景 实现条件的过滤和查询等功能. 2. 说明 跟SQL语句中的where作用相似,都起到了范围的限定即过滤的作用,而判断条件是紧跟后面的条件子句.where主要分为三种形式:简单形式.条件 ...
- 【Java大系】Java快速教程
感谢原作者:Vamei 出处:http://www.cnblogs.com/vamei Java是面向对象语言.这门语言其实相当年轻,于1995年才出现,由Sun公司出品.James Gosling领 ...
- JS案例之2——cycle元素轮播
元素轮播效果是页面中经常会使用的一种效果.这个例子实现了通过元素的隐藏和显示来表现轮播效果.效果比较简单. 效果图如下: 源代码如下: <!DOCTYPE html> <html&g ...
- 机器指令翻译成 JavaScript —— No.4 动态跳转
上一篇,我们用模拟流程的方式,解决了跳转问题. 不过静态跳转,好歹事先是知道来龙去脉的.而动态跳转,只有运行时才知道要去哪.既然流程都是未知的,翻译从何谈起? 动态跳转,平时出现的多吗?非常多!除了 ...
- Android(1)—Mono For Android 环境搭建及破解
0.前言 最近公司打算开发一款Android平台的简单报表查询软件,因本人之前一直是.NET开发的,和领导商定之后决定采用Mono For Android 进行开发,暂时采用破解版进行开发: 下文是记 ...