A picture is worth a thousand words, 一图胜千言。 没错,从 Web 诞生的那天开始,图标就成为视觉层面不可或缺的一个元素,在一个 Web 页面中,一个图标不仅仅能从视觉上带来优雅感,更重要的是,它对此处的功能起到了点睛之笔的作用,它会使得用户更容易理解你的产品。那么,在我们当下的 Web 前端开发中,最常见的图标解决方案有哪些呢?大概是三种,图片、IconFont 和 Svg。图片就不说了,就是整一坨小的 png 图片作为图标,最终把他们合在一个图片里,此种技术还有一个好听的名字 CSS Sprites
,国人称为 雪碧图
,此种方案还是 Web 前端性能优化军规之一,降低 http 请求数来达到提速的目的。
图片咱们今天不说了,没啥意思。咱们今天聊聊 IconFont 和 inline SVG,然后把这两个方案的优劣进行一个对比,然后再介绍介绍常见的 IconFont 库及 inline SVG 的库,最后再展示一个小 Demo 给大家看一看具体在页面上 IconFont 和 Svg 有什么不同。
IconFont 介绍
IconFont 使用的技术是 CSS 自定义字体,用户可以把图标集合打包成字体文件 ( 如何打包,可使用 iconfont.cn ),然后通过 @font-face 来自定义一个字体,最后通过设置 font-family
以及通过使用图标字体的 unicode编码
来使用图标。
在 CSS 里声明字体,编写 unicode 编码对应的图标:
@font-face {
font-family: 'FontAwesome';
src: url('../fonts/fontawesome-webfont.eot?v=4.6.3');
src: url('../fonts/fontawesome-webfont.eot?#iefix&v=4.6.3') format('embedded-opentype'),
url('../fonts/fontawesome-webfont.woff2?v=4.6.3') format('woff2'),
url('../fonts/fontawesome-webfont.woff?v=4.6.3') format('woff'),
url('../fonts/fontawesome-webfont.ttf?v=4.6.3') format('truetype'),
url('../fonts/fontawesome-webfont.svg?v=4.6.3#fontawesomeregular') format('svg');
font-weight: normal;
font-style: normal;
}
.fa {
font-family: 'FontAwesome';
display: inline-block;
}
.fa-icon:after {
content: '\f00c'
}
在 HTML 里这么写就可以了:
<i class="fa-icon"></i>
IconFont 有大量的开源解决方案,而且有很多现成的图标,比较具有代表性的如下:
FontAwesome,具备完善大量的图标库,对于定制化程度不高的项目,可以直接拿过来用
Iconfont.cn,阿里的解决方案,不但有现成的图标供你选择,还可以上传自己的图标来制作 IconFont
IconFont 的最大的好处就是浏览器兼容性好(IE6+),可以通过 CSS 来控制图标大小、颜色。
inline SVG 介绍
使用 IconFont 是把已有的矢量文件(通常是很多 .svg 文件)打包成字体文件,而 inline SVG 则是把 .svg 文件合并成一个大的 .svg 文件,然后在 HTML 中引用这个文件即可,具体步骤参考下面。
合并 svg
在这里搞了三个 svg 文件,准备把他们合并在一起:
<img style="display:block;width:100%;float:none;" src="http://ww4.sinaimg.cn/large/8df27f17gw1f4b11i2l79j20xe0i0acj.jpg"/>
SVG Symbol
我这里使用的是 svg-symbol 方案来合并 svg。
还有一个合并方法是 SVG defs,这个比
SVG Symbol
要鸡肋很多,在此就不介绍了。
通过使用 gulp-svg-symbols 来把 svg 文件合并:
var gulp = require('gulp');
var svgSymbols = require('gulp-svg-symbols');
gulp.task('sprites', function () {
return gulp.src('assets/svg/*.svg')
.pipe(svgSymbols())
.pipe(gulp.dest('assets'));
});
最终得到的 svg 文件:
<svg xmlns="http://www.w3.org/2000/svg" style="width:0; height:0; visibility:hidden;">
<symbol id="circle" viewBox="0 0 200 200">
<g class="transform-group">
<g transform="scale(0.1953125, 0.1953125)">
<path d="..." fill="#272636"/>
</g>
</g>
</symbol>
<symbol id="password" viewBox="0 0 200 200">
<g class="transform-group">
<g transform="scale(0.1953125, 0.1953125)">
<path d="..." fill="#272636"/>
</g>
</g>
</symbol>
<symbol id="profile" viewBox="0 0 200 200">
<g class="transform-group">
<g transform="scale(0.1953125, 0.1953125)">
<path d="..." fill="#272636"/>
</g>
</g>
</symbol>
</svg>
使用方法
在 HTML 文件中声明 svg,然后通过 <svg><use xlink:href="#id" /></svg>
来使用:
<svg xmlns="http://www.w3.org/2000/svg" style="width:0; height:0; visibility:hidden;">
<symbol id="circle" viewBox="0 0 200 200">
<g class="transform-group">
<g transform="scale(0.1953125, 0.1953125)">
<path d="..." fill="#272636"/>
</g>
</g>
</symbol>
<symbol id="password" viewBox="0 0 200 200">
<g class="transform-group">
<g transform="scale(0.1953125, 0.1953125)">
<path d="..." fill="#272636"/>
</g>
</g>
</symbol>
<symbol id="profile" viewBox="0 0 200 200">
<g class="transform-group">
<g transform="scale(0.1953125, 0.1953125)">
<path d="..." fill="#272636"/>
</g>
</g>
</symbol>
</svg>
<svg class="icon"><use xlink:href="#profile" /></svg>
<svg class="icon"><use xlink:href="#password" /></svg>
<svg class="icon"><use xlink:href="#circle" /></svg>
你也可以通过 <svg><use xlink:href="http://cdn.com/assets/symbols.svg#id" /></svg>
来直接使用存储在 CDN 上的 svg 文件,如果感觉每个都要写 CDN 的地址太麻烦,则可以封装 JS 工具,统一维护,统一管理。
inline SVG 目前没有什么特别推荐的开源解决方案,一般情况下,图标都是自己的,自己通过工具打包就已经很方便了,而且很难通过纯 CSS 或 JS 来解决,因为它跟 HTML 的关联性太大了,即使是这样,还是推荐一个库给大家了解了解:
IconFont 与 inline SVG 方案对比
浏览器兼容性
IconFont | inline SVG |
---|---|
IE6+ |
IE9+ , Android 3.0+ 移动端支持很好,现在可以使用 |
尺寸、颜色是否容易控制
IconFont | inline SVG |
---|---|
浏览器会认为它是一个字体,因此只能使用 color 和 font-size 控制,而且尺寸特别不精细 | 支持多色、局部颜色控制、控制尺寸使用 width 和 height |
访问的稳定性
IconFont | inline SVG |
---|---|
Font 在 CDN 上会有跨域问题;而且字体下载不下来是很常见的事;还有一些已知的Chrome的Bug ;貌似代理性质的浏览器,像 UC ,就不支持自定义 Font;一些浏览器拦截插件会拦截自定义字体...... | Svg很正常 |
语义化
IconFont | inline SVG |
---|---|
根本不语义化,你要写多余没有意义的标签,对 SEO 很不利 | Svg 是图形,人家就是图形,而且 SVG Symbol 支持 title 和 description 属性,非常友好 |
用起来是否顺滑
IconFont | inline SVG |
---|---|
自己生成 svg 然后使用工具打包成多个字体文件,然后用 unicode 对应使用 | SVG Symbol 使用打包工具生成 SVG 集合,直接通过 ID 使用 |
IconFont 与 SVG 的 Demo
总结
如果,你的产品需要支持 IE8 及以下,还是推荐使用 IconFont ,因为使用 SVG Symbol 的话,你需要考虑在低端浏览器下的兼容性,常见的做法是,生成一些 png 的图片做 fallback,然后在低端浏览器下显示,把 svg 隐藏.....
如果,你只需要考虑 IE9+ 和 Android 3.0 + ,毫无疑问,inline SVG 是唯一选择!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。