Icon是web开发中很常见的元素。icon的采用很普遍,其易被识别的特征,可以用来吸引、警告用户,并且(如果运用恰当)能在很大程度上提高用户体验。
我们在web中运用icon的时候,选择其实极为有限。
- Icon Spritesheet
- Icon字体
- 内联svg
- svg图片元素
这些都是今天常用的方式,就好比SVG元素和icon字体。在这篇文章中,我们会深入研究web开发中每一种icon的方法,并且会研究哪一种方法的性能最优。
Icon Spritesheet
我们通过许多小的图片(icon图片文件)合并为一份大文件的方式创建icon spritesheet,会用到CSS background-image,background-size和background-position的方法从icon spritesheet中展示图片。
我们可以采用SVG spritesheet来确保在每种显示器上都可以正常展示(普通显示器和Retina显示器)并且可以结合PNG spritesheet作为旧版本浏览器的候选方案。我们可是使用JavaScript库比如Modernizr来侦测用户的浏览器是否能支持SVG,在不支持的情况下以PNG作为备选。
我们来创建一个可行的icon
1 |
<span aria-hidden="true" class="icon icon--email"></span> |
spritesheet CSS例子(可以复制或者手动键入)
1 |
.icon { |
如果你还在想CSS样式hidden–visually是如何隐藏内容的,我在其他一篇我之前的文章中介绍过。
我们一起来评价使用icon spritesheet的优点和缺点吧。
优点
- 增加icon的过程可以很容易被自动化
- 图片优化技术能给压缩spritesheet文件的体积
- 能在所有显示器中正常显示(当SVG spritesheet可用的时候)
- 非常不错的浏览器支持(当PNG做备用方案时)
- 减少请求的次数(当HTTP/2不被使用的时候)
缺点
- 在盒状模型外不可使用。只有在手动添加额外的HTML元素时可用。
- 很糟糕的样式
- 所有的icon的变化都需要作为单独的元素添加到spritesheet中。
- 在多人协作中同时添加新的icon时容易出现冲突。
- 在使用HTTP/2的时候没有任何性能优势。
工具
- Sprite Cow – 在线spritesheet图片、CSS生成器。
- PostCSS-lazysprite – 自动化spritesheet图片和CSS生成器的PostCSS插件。
- gulp-svg-sprite – 自动化spritesheet图片和CSS生成器的Gulp插件。
Icon字体
我们可以制作包含着所需icon的字体文件来替单一的将icon合并成图片文件的方法。浏览器会将icon的字体文件当作样式更加友好文字样式来处理。
有许多制作和管理icon字体、CSS的工具,生成的CSS文件会如下。
1 |
/* Define font icon font family */ |
我们来实现一个icon效果
1 |
<span aria-hidden="true" class="icon icon--email"></span> |
下面是使用icon字体的优点和缺点。
优点
- 更好的优化效果
- 可以在许多的工具中编辑和生成
- 非常友好的浏览器支持
- 易于使用
缺点
- 字体的抗锯齿效果可能会对icon的渲染产生一定的影响
- 在字体文件下载和加载的时候,页面上可能什么都不会显示
- 在用户使用额外字体或者样式重写的时候很容易被覆盖掉
- 在盒状模型外不可使用。只有在手动添加时可用
工具
- icomoon – 管理和生成icon字体文件和CSS文件
- fontello – 管理和生成icon字体文件和CSS文件
- icon-font-generator – 将SVG文件转化为icon字体文件的NPM插件
内联SVG icon
相比起引入某些文件(spritesheet或者icon字体)的方法,我们可以直接将SVG数据嵌入到HTML文档中,浏览器会解析和展示SVG元素,由于我们可以单独设置每一个元素的样式,所以内联SVG元素是高度可定制的。
我们来看一个使用内联式SVG的代码:
1 |
<svg labelledby="titleId descId" role="group"> |
我们使用标签为“titleId descId”作为SVG元素的标题和说明,会让元素对于辅助设备来说更加友好。将role设置为”presentation”也非常重要,因为这样会更加突出SVG的图形部分,并且被辅助设备忽略。
我们一起来评价使用内联SVG的优点和缺点吧。
优点
- 与HTML同步加载,不需要额外的载入时间
- 没有额外的HTTP请求
- 具有良好可读性,无需额外HTML元素支持
- 在不同显示器的解析度中效果都不错
- 就样式选择来说是最优的(甚至可以为
<svg>
元素设置样式)
缺点
- 复杂的HTML文档标记(取决于使用的框架)
- 难以管理和维护(同样也取决于使用的框架)
- icon不会被浏览器缓存
- 许多旧版本(或者很少使用)的浏览器不支持内联SVG
许多框架让icon的管理和维护变得容易。比如说,Webpack会生产版本中将所有在”/path/to/myIcon.svg”引入的文件转变为内联SVG。对于开发人员来说,更加便于管理项目。
svg图片元素
我们可以用<img>
元素来引入单独的SVG文件,而不是一个<svg>
标签。这可以让文件更小而且更加简便而且更加易于维护。
我们用这种方法写一个icon
1 |
<img src="email.svg" alt="Send me an email"> |
我们可以用srcset标记来设置旧版本浏览器的备用方案。
1 |
<img src="email.png" alt="Send me an email" srcset="email.png"> |
支持srcset标记的浏览器同时也会支持SVG元素,而且能自动载入SVG图片。对于不支持此标记的浏览器会自动加载PNG备用方案。
来看一下使用内联SVG图片元素的优点和缺点。
优点
- 标签简单
- 内建简单且可读性高的alt标记的
- 不错的浏览器兼容(如果PNG备用方案可用)
- 可以压缩的图片文件
- 图片文件可以被浏览器缓存(仅需一次下载)
缺点
- 很糟糕的样式
- 不同的icon(比如不同颜色)需要载入不同的文件
- 每一个icon需要许多次请求(在没有缓存的情况下)