X.d 笔记

小Web,大世界

0%

网页字体九成手册

html5诞生以来,字体特性算是一个广受喜爱的特性,但又对于最终用户不算是太友好,毕竟前端不是专业造字人,特别是中文,所以就出现了很多基于字体的框架,软件等。

今天说一下,如果本文看完的话,基本上能解决 90% 的字体问题,所以就叫九成手册,当然你要问我IE,我就呵呵了,再说一次,html5.

图标

一:使用图标库

使用 Icon 是目前来说字体应用最为广泛的了。比较流行的框架有 glyphicons awesome 等等。

记得在不久前(就算是如今),很多网站都没有使用字体来做为图标,而是使用图片,这样会有很多缺点:

  1. 字体文件一般都比较小,包含上百个图标的字体通常不到 40kb,而使用位图,100个图标可能达到 1Mb 以上,而且网络请求 100个小图标,也是不小的开销。
  2. 当然,你也可心使用 css-sprite 技术将这100个小图标压成一幅图片,这样就只请求一次了,但编写css样式的复杂度就会变高很多,即使是用 compass,也要额外写很多。而且当你使用 sprite 图后,就没有办法进行大小控制了。
  3. 使用图片,样式不够灵活,比如放大缩小,颜色等,如果是字体,可以随便调整 font-sizecolor 等属性。
  4. 图片如果拉大后,就会失真,颗粒感强

当然图片有两点好处,目前还使用图片做为ICON的都是基于以下考虑

  1. 图片显示效果可以好一点,比如在PS里面加入各种特效后导成图片,字体就比较难做到
  2. 兼容老古董IE

一般情况下,都是使用 <span class="icon xxx" /> 之类的来放置一个图标,但也有一些框架可以直接使用文字切换,比如 Google 的 MaterialIcon 可以直接写为 <i class="material-icons">book</i>

具体怎么写参考框架就行了,不多讨论,但是即使如此,一般情况下都会受到一定的局限性,有时想要一个好的 ICON 但是图标库中没有是很觉的事。

下面来说一下阿里的 iconfont

二:ICON FONT

(IconFont)[http://iconfont.cn/] 是一个在线图标工具,除了上面有丰富的图标库可以直接使用之外,有设计能力的团队,可以上传自己做好的 SVG 图标进行图标制作。

这里比较一下 使用 iconfont图标库 的优缺点:

项目 iconfont 图标库
字体大小 创建项目后,引把需要的图标加入即可 默认提供字体文件,即使不用也占用空间
可控性 可以随时添加,删除项目内的图标 一般来说每次升级时会有一些新图标加入,但不可控
图标数量 超级多,各种风格,各种类型应有尽有 基本就是默认提供的一套
操作度 每次去页面进行操作后,再下载并引入 很简单,下载引入即可
文档 下载下来包含专属文档 直接官网查看即可

结论就是,如果一套字库就能满足各种需要,用字库即可,没必要使用 iconfont 进行折腾,但如果对于 icon 要求较高,而且总喜欢新奇的,可以使用 iconfont,一般情况下也可以结合使用,即简单又能变通。

字体

字体的主要功能其实还是文字,在没有字体之前,我们通常定义字体为 微软雅黑黑体,之类,这里其实是做了一个假设: 浏览网页的人电脑里面本身就安装了这种字体。

网页找不到这些字体时,会使用系统的默认字体,一般来说中文就是 宋体,英文可能是 Arial 之类的字体。

HTML5 允许引入字体之后,除了在图标上的应用,另外在很多英文网页上也有极大的应用。因为英文字体比较小,总共才100多个字符。所以能看到很多英文网页的字体都很漂亮,虽然你的电脑上并没有预装这些网页使用的字体。

通常来说,字体在中文上没有得到应用主要原因就是中文字体太大了。一套完整的中文字体包括8万多个简体字,大小通常都是 10M左右,网页面上直接引入一个字体都比好几个页面要大了。(当然也有很多为了达到效果就是这么干的)

font-carrier

如果我的网页上,仅仅一部分的中文我需要显示为比较好看的字体,那么我可以通过 font-carrier 这个小工具,把中文字体中的部分文字抽出来,做为显示。

你需要先使用 npm 安装 font-carrier

然后,使用 node 命令去执行以下脚本,它可以将一个中文字里面其中的部分中文抽出来,生成在当前目录下,包含4个字体文件,根据浏览器的不同导入,大小仅 10kb

var fontCarrier = require('font-carrier');
var transFont = fontCarrier.transfer('./张海山锐谐体.ttf');

//固定要转换的文字
var str = ['1234567890'];
str.push('abcdefghijklmnopqrstuvwxyz');
str.push('ABCDEFGHIJKLMNOPQRSTUVWXYZ');
str.push(',.+-=*/<>:;"\'[]{}()');
str.push('需要转换的中文字网页标题');

var text = str.join('');
console.log('转换的文字:' + text);
transFont.min(text);
transFont.output({
  path:'./customfont'
});

最后在网页上引入后,假设定义样式名为 customfont,那么,即可在需要的地方将中文字使用 张海山锐谐体

<h2 style="font-family:customfont">网页标题</h2>

FontForge 合并字体

对于高端用户来说,可能会有这样一个需求,我想让自定义的字体的中文部分保留张海山锐谐体,而英文和数字符号部分使用一个更好的英文字体,比如 Eurostile,是否可实现呢。

这里再介绍另一个工具 FontForge ,是我从网上另外一篇文章看到的,先使用FontForge制作出一个字体,然后再使用 font-carrier 抽取,就可以完美实现。

步骤如下:

  1. 准备一个临时目录,把你要合并的英文字体A、中文字体B放到目录下;
  2. 准备好下面这个脚本,将其命名为font-merge.pe,保存在上述临时目录下:
# Pre-operation for some non-standard Chinese font file
Open("font_b.ttf")
SelectAll()
ScaleToEm(1024)
Generate("temp.ttf", "", 0x14)
Close()

# Open English font and merge to the Chinese font
Open("font_a.ttf")
SelectAll()
ScaleToEm(1024)

MergeFonts("temp.ttf")
SetFontNames("FontName", "Font Family", "Full Name", "Style", "")
Generate("font_merged.ttf", "", 0x14)
Close()

这里注意几点:

  1. 第2行:这里括号里指定中文字体的文件名,和你放到临时目录中的保持一致;

  2. 第9行:这里括号里指定英文字体的文件名,和你放到临时目录中的保持一致;

  3. 第14行:这里设置输出字体的属性,第一个参数是字体的PostScript名,必须英文,不可以有空格,这也是跨平台唯一的标识;第二个参数是字体的family名,第三个是字体的full名,这两个都可以带空格;第四个参数是样式描述,可以是”Regular”、”Bold”、”Italic”等;

  4. 第15行:这里括号里指定输出字体的文件名,和临时目录中已有文件不要重名。

  5. 在上述临时目录下运行下面的命令:

fontforge -script font-merge.pe
  1. 等待命令运行完成,就可以去临时目录取合成好的字体了。这里有时会有一些warning,但是不要紧;某些中文字体会导致出错,比如著名的微软雅黑,由于这个字体内部做了很多hacking所以很多标准工具都处理不了,这类问题暂时没有办法,反正好用的中文字体还有几种,它不行就换别的好了。另外,这里举例用的都是TrueType字体,事实上OpenType也是支持的,其他比较少见的类型,只要FontForge支持就可以用在这里。