[关闭]
@Chiang 2020-07-18T15:40:21.000000Z 字数 2883 阅读 967

iconfont字体生成原理及使用技巧

2020-07 CSS


前段时间遇到过字体跨域的问题,好奇字体的实现原理;找到篇很好的文章,就搬了过来.

我们的解决方案参考

解决css引用字体跨域问题将文字设置为 base64 编码

css加载自定义字体

首先前端都知道我们可以定义web上面文字的fontfamily。

  1. css:
  2. .test{
  3. font-size: 16px;
  4. font-family: '微软雅黑';
  5. }
  6. html:
  7. <span class="test">iconfont字体原理</span>

但是这种情况下我们只能用系统默认的一些字体,限制比较大。比如微软雅黑就是windows下面才有。

其实css是可以自定义字体的,所以我们可以加载自己的字体。

使用 @font-face 定义一个字体family:

  1. css:
  2. @font-face {
  3. font-family: 'iconfont';
  4. src: url('//at.alicdn.com/t/font_1453702746_9938898.eot');
  5. src: url('//at.alicdn.com/t/font_1453702746_9938898.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
  6. url('//at.alicdn.com/t/font_1453702746_9938898.woff') format('woff'), /* chrome、firefox */
  7. url('//at.alicdn.com/t/font_1453702746_9938898.ttf') format('truetype'), /* chrome、firefox、opera、Safari, Android, iOS 4.2+*/
  8. url('//at.alicdn.com/t/font_1453702746_9938898.svg#iconfont') format('svg'); /* iOS 4.1- */
  9. }
  10. .test{
  11. font-size: 16px;
  12. font-family: 'iconfont';
  13. }
  14. html:
  15. <span class="test">iconfont字体原理</span>

这样我们就可以用自定义字体渲染这些文字了。
每一个字都有对应的unicode。比如我们在web上输入跟输入&#x6211;是一样的。浏览器会自动帮你找到对应的图形去渲染。

当然因为兼容性的问题,不同的浏览器需要加载不同格式的字体,所以我们要同时支持四种字体。

字体内部

我们来看下一个字体的样子。

我们可以通过一些软件打开字体,比如fontforge,fontlab。

比如下面的方正大草字体:

方正大草字体

我们打开看下:

方正大草字体edit

可以看到这个字对应的的图形就是我们在网页上看到的样子。另外注意左上角的unicode。是6211,也就是我们的另一种表现形式。

再双击可以看到我这个图形的样子:

我

其实就是一些路径。而这个路径可以用ai,ps,sketch等等来画,画完粘贴到这里。

iconfont1.0

所以我们就可以做一些事情了,我们可以去改造字体,把一个字对应的图形换成我们设计师设计的样子,处理好兼容性就成了我们iconfont的1.0。

当年iconfont1.0是怎样的流程呢:

流程

由设计师手动修改ttf字体对应的图形,我们人工转换出另外四种字体。
这样前台就可以用unicode去引用,就是我们第一代的iconfont的原理。这个成本有点大。

iconfont2.0

其实我们注意到里面有个svg的字体。你用文本编辑器打开会发现他是xml格式的,每个字的图形对应了一个路径。这个路径就是我们svg里面的path对应的序列。

svg

好了于是我们有了一个全新的思路,由设计师上传svg,我们存储下来,然后大家自由组合,由平台拼出对应的svg字体,然后再转换到不同的其他格式的字体。

平台

这里面的难点主要在,我们要分析svg。转换出对应的path序列。用户上传的svg格式太多,大小不一。要做各种转换,这里不展开了。

这就是我们的iconfont2.0,也就是目前线上跑的版本。

font-carrier

当然这一切都封装好了,做了一个工具库,font-carrier

font-carrier

语法比较简单,可以直接往一个字体里面添加svg,也可以拿到某个字对应的svg,最终导出四种兼容字体。

知道了原理,以后大家调试就比较简单了,直接自己打开对应的svg字体,去看看你们对应的unicode的图形是不是有问题就行了,下面我们说说使用上一些常见的问题。

unicode取值的问题

unicode其实没有特别的规定。

字体有几个私有平面:

私有平面

很早以前我们使用的五位数的,结果现在chrome支持不太好,后面建议大家使用第一个平面里的。

这样用的好处是,字体没有加载的时候,显示的是一个框 口。而不是乱码。(!!意外收获!!)

字体基线的问题

这是个艰难的决定。

中文字体没有严格意义上的基线。我们参考了方正字体的基线:

基线

中间的线是baseline,这个就是0这条线。对于一个字体来说,可以设置上边界(ascent)跟下边界(descent)。比如我们iconfont设置的是812,-212。

所以如果我们的图标这么设计:

对齐

那么是可以基本对齐的。

但是我们发现用户上传图标时喜欢撑满整个框:

整个框

可以想像下,这种图标跟字体一起展现,就会变得偏下了。

单个icon撑开的问题

有的时候设计师设计的icon会有多余的点,也可能当前上传的svg边界太大,于是导致我们的整个字体被撑开。

表现如下:

撑开

可以看到由于最左边的icon把字体撑开了。导致大家展示出了问题,表现在页面上是:

注意看里面的阴影,由于被撑开,导致它的边界是不对的。我们删掉这个图标再生成字体就好了。

当然这里还有各种问题,字体清晰度,icon上传svg规范问题,字体跨域问题(这里居然没展开讲),锯齿问题等等。这些平台基本都可以内部优化掉了,就不展开了。

结语

iconfont解决了我们以前大量使用图片带来的种种问题,但是也有自身的各种缺陷。比如不支持多色就是一个最大的致命伤,另外在不同浏览器下的表现不同,需要做各种兼容。

不久的将来iconfont应该会被svg symbol技术替换。可以参考这篇文章
淘积木目前接入了webfont,直接用svg当作字体展现,实时预览,也是一种新的突破。

iconfont.cn平台目前也在做相关的改造,期待带来新一轮的字体使用方式变革。


参考资料:
iconfont字体生成原理及使用技巧
解决css引用字体跨域问题将文字设置为 base64 编码
https://www.cnblogs.com/victorlyw/articles/9970805.html
css中有些属性的前面会加上“*”“_”,请问分别表示什么意思
计算机中字体的原理是什么
iconfont的实现原理及如何使用

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注