简析字体图标(icon-font)渲染到浏览器的整个过程

字符 unicode 编码

计算机操作系统里面每个字符都有一个 Unicode 编码,每个字或者字符都有对应的 Unicode 编码
页面上显示的字使用 js,css, html 语法表示不太一样,可以了解一下

语法 表示 示例
js \u + 16进制的 Unicode 编码 如 \u97e9 表示汉字“韩”
html &# + 10进制的 Unicode 编码 + 英文分号(可省略) 韩表示汉字“韩”
css \ + 16进制的 Unicode 编码 如 \97e9 表示汉字“韩”

Unicode 字符集里面,E000 至 F8FF 属于用户造字区,用户可以在字体文件里面随便定义这些字符的形状

字体文件

字体文件的作用是规定某个字符编码应该用什么形状来显示,在用户造字区范围内,用户可以在字体文件里面随便定义这些字符的形状

现在用的比较多的字体类型有 eot、svg、ttf、woff 等

如何制作字体文件本文不做介绍,有兴趣的可以自行百度,下文将会提供 svg 转其它字体的工具链接

css 文件引入图标字体

造好图标字体文件之后需要在 css 中引入这些字体文件

@font-face {
  font-family: 'icomoon';
  src:  url('fonts/icomoon.eot?p6awzt#iefix') format('embedded-opentype'),
    url('fonts/icomoon.ttf?p6awzt') format('truetype'),
    url('fonts/icomoon.woff?p6awzt') format('woff'),
    url('fonts/icomoon.svg?p6awzt#icomoon') format('svg');
  font-weight: normal;
  font-style: normal;
}
  • font-family: 自定义字库名称(一般设置为所引入的字库名)
  • src:设置字体的加载路径和格式,通过逗号分隔多个加载路径和格式
  • url:字体文件的存放路径,可以是相对路径也可以是绝路径
  • format:自定义的字体的格式,主要用来帮助浏览器识别,主要有以下几种类型:truetype、opentype、truetype-aat、embedded-opentype、avg 等
  • font_weight:定义字体是否为粗体
  • font_style:定义字体样式,如斜体

定义的字体由于种种原因很可能会被浏览器覆盖,所以做了下面的工作

[class^="icon-"], [class*=" icon-"] {
  /* use !important to prevent issues with browser extensions that change fonts */
  font-family: 'icomoon' !important;
  speak: none;
  font-style: normal;
  font-weight: normal;
  font-variant: normal;
  text-transform: none;
  line-height: 1;

  /* Better Font Rendering =========== */
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

为了防止字体被覆盖可以看到在 font-family 上使用了 !important,并且做了一些字体样式的优化,其中 font-family 是必须的

上面的样式写在了 [class^="icon-"][class*=" icon-"] 上,这两个 css 选择器的意思是只要 html 标签有以 icon- 开头的类就会起作用,例如:

<i class="icon-home"><i>
<i class="other icon-user"><i>

字符插入

认真思考过的朋友会发现,为什么不直接在 html 里面输入 Unicode 编码来显示图标呢?这里有三点考虑:

  • 直接在 html 里面使用 Unicode 需要先把 16 进制转化为 10 进制
  • 直接在 html 里面使用 Unicode 不容易维护,因为使用的地方可能分散在各处
  • 因为浏览器会覆盖 font-family 所以直接在 html 里面使用 Unicode 不会正常显示

所以一般都会采用 css 来引入 Unicode,看下面的代码

.icon-home:before {
  content: "\e6db";
}

上面的代码会在类为 .icon-home 的标签中插入 \e6db 对应的图标
如此,上文中的 <i class="icon-home"><i> 就会渲染出对应的图标

整个 css 文件代码

@font-face {
  font-family: 'icomoon';
  src:  url('fonts/icomoon.eot?p6awzt#iefix') format('embedded-opentype'),
    url('fonts/icomoon.ttf?p6awzt') format('truetype'),
    url('fonts/icomoon.woff?p6awzt') format('woff'),
    url('fonts/icomoon.svg?p6awzt#icomoon') format('svg');
  font-weight: normal;
  font-style: normal;
}

[class^="icon-"], [class*=" icon-"] {
  /* use !important to prevent issues with browser extensions that change fonts */
  font-family: 'icomoon' !important;
  speak: none;
  font-style: normal;
  font-weight: normal;
  font-variant: normal;
  text-transform: none;
  line-height: 1;

  /* Better Font Rendering =========== */
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.icon-home:before {
  content: "\e6db";
}

.icon-user:before {
  content: "\e6db";
}

/* 上面只列举了两个图标,可继续添加其它图标 */

工具推荐

市面上已经有不少字体生成的网站,例如
https://icomoon.io/
https://www.iconfont.cn/

网站交互比较简单,只需要把画好的 svg 图标或者是从别的平台获取的 svg 图标上传上去再导出字体文件即可,下图为 icomoon 页面图示

图片加载失败

有兴趣的可以去 https://icomoon.io/ 试试看吧!

除特殊说明外本人博客均属原创,转载请注明出处:http://blog.johnhan.cn/blog_1043.html
鄂ICP备17018604号-1  鄂公网安备42060702000030号