之前写了一篇关于雪碧图的博文, 评论里有说用http2、或用SVG也有说用图标字体代替,大家知识面是挺广,但深入了解技术点的似乎却不多,否则不会有雪碧图过时无用,用http2或图标字体取代就好了的想法;http2后续有时间再写一篇个人实践、理解博文, 本文主要讲图标字体(iconfont)技术点,从实践开发角度讲述个人对图标字体的理解。
一.iconfont使用场景(优缺点);
一般我们项目决定要使用一个技术点前,会查相关资料对其有大概的理解。例如, 这次要使用iconfont实现功能, 理解相关资料后归纳、总结出它的优、缺点以及它的使用场景。
图标字体优、缺点:
1.优点;
轻量(文件体积小)、灵活(样式可改变图标)、兼容性好(IE8+)。
2.缺点;
图标只能单色调(太复杂的多色图标无法实现)、生成图标字体相对花时间。
跟webfont一样iconfont实现的关键代码是“@font-face”(细谈CSS@font face)查看其浏览器兼容信息为IE8+:
低版本浏览器其实也有方法兼容,icoMoon是图标字体开发时生成字体文件及demo的网站,用过icoMoon的同学都知道其有一个“Support IE 7”选项, icoMoon IE7支持实现原理:样式上用*zoom 触发重绘(触发haslayout), 脚本上检测 关键字className动态插入dom节点实现;考虑到IE7目前的市场份额,以及该方式带来的性能消耗,本人不建议去兼容。
另外,图标只能单色调这个问题也有办法解决,阿里巴巴iconfont+ 也是图标字体开发时生成字体文件及demo的网站;阿里巴巴iconfont+ 生成的demo可以解决图标单色调问题,其原理是 生成svg合集, 然后使用svg呈现图标。但该方式兼容性较差(SVG兼容小结), 如是移动端开发不考虑低版本浏览器兼容问题可以尝试该方式。
根据以上图标字体的优缺点, 个人总结的使用场景如下:
1.web app(H5) 小图标 放大失真问题解决;
移动页面大多数情况没办法用雪碧图,用了雪碧图表示图片大小固定了,而移动端需要兼容不同屏幕大小的移动设备,这就需要图片是可以根据屏幕尺寸而改变的。 如果你的图尺寸是固定的,那就可以用雪碧图。
2.PC端小图标性能更佳、小图标尺寸修改不用改原图;
PC端页面优化,可将部分雪碧图换成小图标,字体图标比雪碧图的http请求少、体积小;(加载一个页面时分模块开发关系可能有多张雪碧图,但使用字体图标,文件一个就够)
PC端做换肤业务时,使用了字体图标实现起来更加的优雅、方便。(之前做页面换皮肤功能时发现换肤时小图标得多出一套雪碧图略麻烦, 如果是字体图标直接更新颜色样式就OK)
知乎、斗鱼、Bilibili这类网站不少地方使用了雪碧图,如果我们维护这类网站,能用图标字体替换么?
从两方面考虑:
1.开发时间成本问题, 使用自定义图标字体替换雪碧图需要一定时间,如果要求快速更新小图标建议维持用雪碧图;
2.字体小图标兼容、单调色问题, 如果网站需要兼容低版本浏览器、且图标复杂、或者多色那还是得用雪碧图。
所以实现小图标时雪碧图 跟 图标字体会在一个网站共存,自定义图标字体 为什么比较耗时,且太复杂图标无法实现?请往下看iconfont开发流程就了解了。
二.iconfont开发流程;
接下来就是本文篇幅最大的章节, 我将从自己实现图标字体小demo上详细的列出所有步骤。
使用免费图标字体:
如果网站使用的不是自定义的图标字体,而是网上开源的免费图标那实现上将非常的简单;
例如, 我要使用阿里巴巴iconfont+ 上的图标字体, 进入网站并登陆(可以用github账号登录),从图标库选取自己喜欢的图标:
这里我选取了三个小图标,点击右上角购物车,将选取的图标添加到新建项目,然后点选“下载至本地”:
下载下来的压缩包就包括了 三小图标字体文件, 以及三种实现方式的demo;
下载图标字体的三种用法,打开对应html(demo_fontclass.html、demo_symbol.html、demo_unicode.html)文件即可了解(也可直接打开我demo里的这三个文件查看用法,所以用法这里不冗述了);有4个字体文件(EOT/SVG/TTF/WOFF)是为了兼容所有浏览器,因为不同浏览器对字体格式兼容是不一样的:
使用自定义图标字体:
实际开发中基本都是使用自定义生成的图标字体,大致步骤如下:
1)使用PS-矩形工具 生成图标;
2)AI软件打开PSD文件,File->Scripts->SaveDocsAsSVG 生成SVG文件;
3)访问阿里巴巴iconfont+(或iconMoon)上传SVG生成字体文件;
PS: 教程雪碧图vs图标字体 中多了PS导出AI文件的步骤,经实践PS生成的AI文件打开容易显示空白,且AI软件可直接打开PSD文件,该步骤可省略.
其实生成自定义图标字体一般交给设计部同事完成(可能设计同事是用Sketch而不是PS生成小图标), 因为要了解整个流程细节,所以请教了设计部同事生成自定义图标字体的技巧跟方法; 这里就分享下生成自定义图标字体的具体流程:
首先,下载生成小图标的软件: PS(Photoshop)、AI(Adobe Illustrator);
PS下载地址:mac 版、windows版
AI下载地址:mac 版、windows版
1)使用PS-矩形工具 生成图标;
预计demo功能: 三个小图标:笑脸、黑脸、帽子; 默认显示笑脸+帽子,鼠标hover,变成黑脸+帽子(颜色变绿);
将要实现的小demo将有三个小图标, 接下来就使用PS生成这三个小图标;
无论是用Sketch还是Photoshop绘制小图标的思路都差不多,使用各种基本图形相加相减得到想要的小图标;所以太复杂的图形实现起来会耗时甚至无法实现。(PS矢量小图标制作、Sketch小图标制作技巧)
笑脸PSD:
使用PS新建165px * 124px 图层, 使用 “圆角矩形工具”创建100px*100px的圆(颜色#666):
继续用 “圆角矩形工具”绘制小图标的眼睛(为了直观可改成白色):
ctrl+e(command+e)
合并形状并选择“排除重叠形状”:
小图标的嘴巴有点复杂,使用钢笔工具或使用两个圆形相减(“排除重叠形状” )+矩形工具(“与形状区域相交”)生成嘴巴:
然后
ctrl+e(command+e)
合并形状并选择“排除重叠形状”生成笑脸:
黑脸PSD:
与笑脸PSD一样流程, 只把嘴巴旋转180度就行:
帽子PSD:
使用PS新建165px * 124px 图层, 使用 “椭圆工具”创建150px20px的椭圆(颜色#666),然后画一个90px110px的椭圆:
在第二个椭圆图层使用矩形工具(“减去顶层形状”)删减该椭圆内容然后与第一个椭圆 ctrl+e(command+e)
合并形状:
2)AI软件打开PSD文件,File->Scripts->SaveDocsAsSVG 生成SVG文件;
生成三个小图标的PSD后,我们使用AI软件打开三个文件, 然后分别处理生成SVG文件:
3)访问阿里巴巴iconfont+(或iconMoon)上传SVG生成字体文件;
将上述步骤生成的SVG文件在阿里巴巴iconfont+中上传,然后这几个小图标就在“我上传的icon”中:
将图标添加入库, 然后添加到项目, 最后就能下载字体及demo到本地了:
字体文件下载好后, 就能轻松实现我的小demo:
三.iconfont实践注意事项.
1.生成图标字体注意事项;
截图来自阿里巴巴iconfont+;
更多生成图标字体注意点,请阅读参考资料中《雪碧图vs图标字体》->如何制作图标字体;
2.使用图标字体注意事项;
跨域问题
1)配置自己的服务器;
# For Apache
<FilesMatch ".(eot|ttf|otf|woff)">
Header set Access-Control-Allow-Origin "*"
</FilesMatch>
# For nginx
location ~* \.(eot|ttf|woff)$ {
add_header Access-Control-Allow-Origin *;
}
2)放在同一个域;
3)使用base64置入CSS中(Icomoon在导出图标时,设置里勾选Encode & Embed Font in CSS选项,IE8+支持base64)。
字体图标出现锯齿的问题
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
@font-face与性能问题
1)只在你确定你非常需要 @font-face的时候才使用它;
2)将你的@font-face定义在所有的script标签前;
3)如果你有许多字体文件,考虑将它们分散到几个域名下;
4)不要包含没有使用的 @font-face声明——IE将不分它使用与否,通通加载;
5)Gzip字体文件,同时给它们一个未来的过期头部声明;
6)考虑字体文件的后加载,起码对于IE。
--以上使用图标字体注意事项来源《浅谈图标字体》;
关于字体文件跨域可能是大家最关心的问题, 三种解决跨域的方式中base64至入CSS是比较主流的做法,例如 小米官网 的小图标就是用base64至入CSS中实现。
Icomoon在导出图标时,设置里勾选Encode & Embed Font in CSS选项
目前 Icomoon 勾选生成base64样式会出现收费的问题,那目前实现base64至入CSS有哪些方式呢?
1.使用在线 网站将字体文件 生成base64样式;
百度关键字“图标字体转base64”能找到不少, 这里推荐 转base64在线工具 ;
在线工具要求源文件不能大于100K,如果文件过大可以考虑本地构件工具;
2.使用webpack、gulp等构件工具在本地将字体文件转成base64样式;
本demo使用 gulp base64 实现转换:
PS: 本demo的“base64”指令 配置的有点粗糙, 如果在生产中会考虑 接受参数 以及 自动将生成的样式合并到 指定样式文件等,大家可以查看 gulp base64 官网了解更详细的使用方法。
参考资料:
本文对应源码: