首页 > 前端 > 移动Web字体的使用

移动Web字体的使用

在网页开发中使用字体是一个非常重要的部分,它与视觉感受和用户体验直接相关,尤其是在当下移动化的互联网时代,对字体的使用越来越讲究。

一、不同设备的字体表现

以往做PC端页面时,一直喜欢用"Microsoft Yahei","微软雅黑"来作为默认font-family,毕竟是中文字体中比较好看的一种,但是到了移动端,字体的表现就没有那么的’乖巧’了——并不是真正的微软雅黑,而是使用手机默认字体。也就是说IOS和Android系统不支持微软雅黑这种字体,下面是两种手机系统对字体的支持情况:

ios 系统

  • 默认西文字体:Helvetica Neue
  • 默认中文字体:Heiti SC (黑体)
  • 其它常用西文字体:Tahoma、Arial、Verdana、Georgia
  • 不支持微软雅黑字体

android 系统

  • 默认西文字体:Roboto
  • 默认中文字体:Roboto
  • 其它常用西文字体:Arial
  • 不支持微软雅黑字体

这里有一个Demo,可以扫码查看不同设备的字体表现:

mobile-web-font

以下是我对三个品牌手机进行的测试,显示的是系统默认的字体:

mobile-default-font

再对比PC端看到的使用了微软雅黑的字体:

 

Screenshot_3

 

不难发现,使用手机系统默认字体跟微软雅黑字体的表现结果,其实差别并不是很大。比起PC端,移动端设备的默认字体明显好看得多了,所以一般情况下不需要设置font-family

但是,万事总有例外——人类总会产生一些微妙的情感:

  • 我无法控制我这颗追求不一样的心
  • 老板大Boss说带宽什么的都不重要,我就是要NB的页面
  • 产品GG说的好像很有道理,我们要追求用户体验
  • 设计MM说的也对,我想和她做朋友:)

大家都没错啊,现在都是21世纪看脸的时代了,下面这些字体明显更棒好吗!

Screenshot_4

面对这些充满激情的人类,我们需要有新的方案:

  • 自定义的字体写进图片里
  • 使用WebFont引入字体文件

第一种方案适用于页面包含的所有文字已知的情况,操作简单但不具备可编辑性。第二种方案适用性较广,接下来详细介绍。

二、Web Font

1.使用Web Font

WebFont技术提供了在网页使用自定义字体的可能,它的实现原理是让客户端浏览器先下载好我们设置的特殊字体,然后直接应用到网页上的文字上(不需要安装到系统中)。目前的浏览器对Web Font的支持已经非常好,在caniuse上可以看到基本是全平台兼容。

WebFont的实现方法是通过CSS@font-face引入字体,然后把字体应用在相应的文字上:

@font-face{
	font-family: myFontName;
	src: url('myFontName.ttf');
}

p{
	font-family: myFontName,sans-serif;//加一个备选字体以防自定义字体加载失败
}

关于字体的格式,常见的有EOT, TTF/OTF, WOFF, WOFF2, SVG这几种,早期为了兼容通常会见到这种写法:

@font-face {
    font-family: '字体名';
    src: url('字体名.eot'); /* IE9 + */
    src: url('字体名.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
             url('字体名.woff') format('woff'), /* 现代浏览器 */
             url('字体名.ttf')  format('truetype'), /* Safari, Android, iOS */
             url('字体名.svg#grablau') format('svg'); /* Legacy iOS */
}

但是现在各平台尤其是移动端对.ttf格式的支持已经很好,所以通常只需要加载这一种字体格式。

2.使用Web Font带来的问题——中文字体体积大

缘由

与英文字库的26个字母相比,中文字库的体积明显大得多,常用汉字也要3500个左右,所以大多数字体文件会有几M的大小,这就带来了不可忽视的额外的带宽开支问题。

解决方案

也许你并不需要加载完整的字体。

如果你的页面使用到的文字可以枚举,也就是说有限的文字要自定义,那你大可删除字体文件中不必要的文字,只保留用到的文字。这里有两个不错的工具:有字库字蛛,都可以实现该需求。

有字库主要在浏览器中手工操作,在其官网选择一个字体,然后输入你会用到的文字,然后有字库的服务器就会帮你生成压缩后的字体文件:

Screenshot_5

而字蛛(font-spider)通过npm安装到本机环境,使用命令行本地压缩字体,比较适合工程化的场景:

Screenshot_6

两种工具的原理都是删除没用到的文字,压缩字体原文件,从而解决中文字体体积大的问题。

此外,一开始选择字体的环节多花点时间,挑一些本身体积就比较小的字体,能从源头上大大减少带宽消耗。

3.使用Web Font带来的问题——浏览器渲染时的不友好体验

缘由

在网速比较慢的情况下,会看到比较糟糕的渲染过程:

load-font-slowly

 

解决方案

出现这种问题,终究还是因为字体还未下载完成便显示出页面,这里可以通过字体预加载技术解决,目前接触过两种方法:prefetch和@font-face。

prefetch

这是HTML5的页面资源预加载特性(Link prefetch),实现方式即在html头部加入如下代码:

<link rel="prefetch" href="myFontName.ttf">
  • 优点:实现简单,只需一行代码
  • 缺点:只支持安卓设备,ios设备目前不会执行预下载操作

注:真机调试的时候,需要通过fiddler查看是否有字体请求缓存,从而来判断当前浏览器是否支持

@font-face

这种方式的使用场景有点特殊。例如我们有两个页面a.htmlb.html,a是简单的登录页面,而真正使用到自定义字体的是b页面,用户要经过a页面的登录之后才能访问b页面。通常登录页面需要进行输入操作,时间为十来秒到二十几秒,这段时间的浏览器下载线程往往是出于空闲状态,那么我们就可以利用起来,预先下载b页面才会用到的字体文件。所以本方案的思路就是,在a页面设置一段不会显示在屏幕上的段落,然后给它设置font-family使用我们的自定义字体。

那么现在问题来了,怎么实现呢?

  • 在a页面随便找个字硬加上font-family?但是又会落入渲染裸露的轮回问题
  • 在a页面添加一段字,设置display:none?然而测试发现浏览器并不进行加载
  • 那设置visiable:hidden呢?结果占了位置影响布局…

后来想到了一个终极方案——通过position:absolute将元素移到可视区以外:

/* 为b.html预加载字体 */
@font-face {
    font-family: myFontName;
    src: url('myFontName.ttf');
}

.font-abc {
    font-family: myFontName;
    position: absolute;
    top: -9999px;
    left: -9999px;
}
  • 优点:全平台兼容(主流ios、android设备)
  • 缺点:有点hack性质的实现,不够优雅

4.版权问题

回到开篇使用微软雅黑的场景,可能有人会问:既然有Web Font技术,那么我们为什么不直接用@font-face引入这种字体呢?

当然不行!

之所以能在电脑上使用,那是因为你买的电脑装的windows相当于已经购买了微软雅黑字体的版权,而对于其他地方则是没被授权的。要使用@font-face引入微软雅黑这种字体,那么我们事先得上传字体文件到我们的服务器,这样属于未经授权使用了受法律保护的商业产品,构成了侵权行为,有人也曾去咨询了微软官方:在网站中使用微软雅黑字体是否会构成侵权?

不少中文字体都是有版权的,使用前需查清楚,不单是@font-face,图片上使用字体也得留意,方正找淘宝店维权的这个例子就很典型。

虽说有版权保护,但是有些会有个免授权的使用范围,例如汉仪的字体,之前还打电话过去咨询了他们的客服,得到回复是允许非商业性的使用,也就是说个人博客、学校网站、协会论坛等等用他们的字体都是可以的。如果是涉及商业性的业务场景需要用到好看点的字体又怎么办呢?这里推荐站酷字体,现在有站酷酷黑体、站酷意大利体、站酷快乐体、站酷高端黑体四种字体,都很好看,可以免费自由地使用(包含商业)。

三、字体大小的设置

1.使用rem

在W3C规范中是这样描述rem的:

font size of the root element.

简单的理解,rem就是相对于根元素的font-size来做计算。而我们的方案中使用rem单位,是能轻易的根据的font-size计算出元素的盒模型大小。而这个特色对我们来说是特别的有益处。

现在大部分浏览器IE9+,Firefox、Chrome、Safari、Opera ,如果我们不修改相关的字体配置,都是默认显示font-size是16px即

html {
    font-size:16px;
}

那么如果我们想给一个P标签设置12px的字体大小那么用rem来写就是

p {
    font-size: 0.75rem; //12÷16=0.75(rem)
}

2.适配多种移动设备

这里使用手淘的解决方案flexible.js来进行跨设备适配。对于字体来说,默认写个dpr为1时的字体大小,然后根据不同dpr下的值去匹配不同的字体大小:

/* dpr=1(默认) */
div { 
	font-size: 12px;
}

/* dpr=2 */
[data-dpr="2"] div { 
    font-size: 24px;
}

/* dpr=3 */
[data-dpr="3"] div { 
    font-size: 36px;
}

四、页面交互

移动设备支持长按页面,会出现复制文字或者弹出菜单,这种功能有时会破坏用户体验,尤其是H5场景。如果不需要,可以通过css来屏蔽这种功能:

html, body {
    -webkit-user-select: none;   /* 禁止选中文本 */
    user-select: none;
}

a, img {
    -webkit-touch-callout: none; /* 禁止长按链接与图片弹出菜单 */
}

五、总结

  • 不同于PC端字体设置的五花八门,移动端其实不太需要操心
  • ios和android都有自己的默认字体,它们的显示区别并不大
  • 如无特殊需求,手机端无需定义中文字体,使用系统默认即可
  • 若要使用自定义字体,需考虑字体压缩、预加载和版权等因素
  • 要对字体大小进行适配,这里使用的是手淘的解决方案flexible.js

 

扩展阅读:

 

 


本文标题:移动Web字体的使用
转载请注明出处,欢迎分享


2 COMMENTS

  1. 缙哥哥2017-08-10 am10:37

    据说我的主题最新版本很吊,然而我不是正版,没钱的屌丝真可怜……