如何在网页中插入 icon
从古至今人类就用图标作为交流工具,通过视觉语言来传达信息。比如 象形文字,皇族图腾等。而现今 Web 和 UX 设计的兴起,在 Web 中几乎没有网站或者 APP 没用使用 icon 了。比如 各类网站的分享到微信的微信 icon,点赞的大拇指 icon 或者 心形 icon,还有各种表情 icon。如何在网页中插入 icon 呢?
直接插入
最简单的是用 <img>
插入图片 icon 图片,代码如下:
<img src="icon-wechat.png" alt="微信" title="分享到微信" width="25" height="25" aria-hidden="true" /> 分享到微信 |
可能会有这样的一个场景,PM 希望鼠标 hover 的时候,icon-wechat.png 能被体现出来鼠标经过它了,然后设计师就给了一张图 icon-wechat-hover.png,这个时候咱们可以把 icon-wechat-hover.png 放到另一个 <img>
里,然后再用 CSS 的伪类:hover
来实现效果。
<span class="share-2-wechat"> |
.share-2-wechat img:nth-child(2) { |
缺点是:
- 对这样一个小小的效果会发送两个 HTTP 请求,现在 HTTP/2 时代来了也还好了
网站为了使请求数减少,通常采用对页面上的图片、脚本进行极简化处理。但是,这一举措十分不方便,也不高效,依然需要诸多HTTP链接来加载页面和页面资源。
HTTP/2引入了服务器推送,即服务端向客户端发送比客户端请求更多的数据。这允许服务器直接提供浏览器渲染页面所需资源,而无须浏览器在收到、解析页面后再提起一轮请求,节约了加载时间。
CSS 背景图
把 icon-wechat.png 作为 .share-2-wechat 的背景,hover 的时候把背景图片换成 icon-wechat-hover.png。
<span class="share-2-wechat"> |
.share-2-wechat { |
代码量上看,CSS 背景图的方法要比直接 image 插入的方法代码少了不少,而且代码也更加清晰。但它的缺点和直接 image 插入法一样,会有两个 HTTP 请求。同时因为 hover 的时候图片 icon-wechat-hover.png 其实是还没有下载的,所以这个时候如果网速慢 .share-2-wechat 框框里会出现一个空白期,然后等 icon-wechat-hover.png 加载完了才会显示,即一个闪屏的现象。
CSS sprite 精灵图
CSS sprite 是把所有的 icon 都合并到一张图片上,然后用 background-position 控制图片的位置以显示对应的 icon。
.share-2-wechat { |
有许多工具可以实现 CSS sprite 图,以及对应的样式代码。比如:stitches。缺点是后期维护修改不方便。如果某个 icon 的位置变了,影响到其他 icon 的位置,那整个 icons.png 相关的 icon 的样式都得修改,工作量不小哇。
Icon Font 字体图标
如果 icon 的颜色都是单色的时候,可以用这个方法 iconfont
它的大致原理是
把 icon 画到一个字体文件里面,并给每个 icon 设置一个对应的 Unicode。这里的 Unicode 码位必须是 PUA (Private Use Area) 的 E000 - F8FF,Unicode 特意保留的自定义字符的区域,一共有 6400 个码位。网上说:阿里巴巴的 iconfont.cn 没有遵循这个最佳实践,用的是 CJK(Chinese Japanese Korean 中日韩统一表意文字)编码区间(U+3432)。还说,当浏览器加载字体出问题时,会还原成一些奇怪的中文文字,这对读屏软件也非常不友好。好在它的管理后台,可以手动的编辑这个 code point。但是其实他们设置的编码是 E6xx 的码位。
CSS 里设置 @fontface 的 src 指定为这个字体文件,定义它的 font-family。
/* 这里复制的 iconfont.cn 帮生成的字体文件,然后可以直接用的 font-face 代码 */
@font-face {
font-family: 'iconfont';
src: url('//at.alicdn.com/t/font_681540_s4ya5or4w75jyvi.eot');
src: url('//at.alicdn.com/t/font_681540_s4ya5or4w75jyvi.eot?#iefix') format('embedded-opentype'),
url('//at.alicdn.com/t/font_681540_s4ya5or4w75jyvi.woff') format('woff'),
url('//at.alicdn.com/t/font_681540_s4ya5or4w75jyvi.ttf') format('truetype'),
url('//at.alicdn.com/t/font_681540_s4ya5or4w75jyvi.svg#iconfont') format('svg');
}设置为第 2 步定义的 font-family
[data-icon]::before {
font-family: 'iconfont';
}content 为图标对应的 Unicode
[data-icon]::before {
content: attr(data-icon);
}
.share-2-wechat:hover {
color: green;
}<span class="share-2-wechat">
<i
aria-hidden="true"
data-icon=""
></i> 分享到微信
</span>
Icon Font 的问题是,字体只能是单色,最多实现渐变色,是不能实现彩色的。而 SVG 是可以实现彩色的 icon 的,可以给它的每个 path 或者其他标签单独加不同的颜色。
SVG icon
SVG Scalable Vector Graphics 可缩放矢量图形,是一种基于可扩展标记语言 XML,用于描述二维矢量图形的图形格式。也是 W3C 制定的标准之一。
- SVG 可以直接插入到网页,成为 DOM 的一部分,并且可以用 CSS 和 JavaScript 操作
- SVG 也可以写入一个独立文件中,再用
<img>
、<object>
、<embed>
、<iframe>
等标签插入网页中 - SVG 文件也可以作为 CSS 的
background
- SVG 文件还可以被转为 base64 编码,然后作为 Data URI 写入网页
彩色的 SVG icon
如下 SVG 代码,可以看出控制 <path>
的 fill 颜色就可以产出彩色的 icon 啦:
<svg style="width: 3em; height: 3em;" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"> |
icon 图就是下图啦:
用 Symbol 实现 SVG Sprite
SVG Sprite 是把所有的 icons 放到 一个SVG 文件里,一个 icon 对应 一个 symbol,用 symbol 的 id 来标识每个 icon,在需要插入 icon 的位置<use xherf:link="sprites.svg#icon-xx"></use>
插入。
<!-- sprites.svg 里面定义 symbol --> |
CSS 预编译处理器
如果是用预编译器编写 CSS,个人更倾向于 database64,不管是矢量还是位图。
CSS 画 icon
还有其他有意思的 cssicon.space,作者用 CSS 实现了各种图标。
参考链接
Markup-free icon fonts using unicode-range
Creating an Icon Webfont
The pros and cons of icons in web design
HTML for Icon Font Usage
SVG 图像入门教程
Styling SVG Content with CSS