首页 > 开发 > CSS > 正文

Web 字体的渲染和加载的问题

2017-09-12 09:39:59  来源: 网友分享

制作网页过程中,有时使用了大量的自定义字体。这些字体在不同浏览器中渲染的效果不一致,有时偏粗,有时偏细。这种情况如何避免?

如果font-famaily属性只写自定义的字体,当文字出现时候可能字体还没加载完毕,这会文字不会出现。那么字体如何进行预加载?

字体转换的时候,原始字体的格式是否有区别,是用OTF还是TTF?

解决方案

2/15更新:做了一番调查,对字体渲染结果的控制给出一些初步的方案。


关于字体渲染效果不一致

关于字体显示,必须接受的一点事实是:它完全取决于用户操作系统和浏览器实现的上下文,大多终端上都仅仅对用户开放控制字体的渲染的开关,而缺乏相应的控制接口或CSS属性。

这里有一个字体渲染实测结果截图展示。造成渲染区别的主要是以下几点(wiki: Font rasterization):

  1. 字体抗锯齿:Win7以上自动打开的ClearType(msdn)、常见于Mac OS和MacType的次像素平滑(原理)、常用于Android和iOS等移动设备的灰度渲染
  2. Hinting技术 /wiki
  3. 对字重font-weight的支持程度不一(ref

相对应的控制有:

  • 字体抗锯齿技术:仅仅只有webkit核支持使用一个CSS属性来控制字体平滑技术:-webkit-font-smoothing: antialiased;,可以将chrome浏览器的字体渲染调为灰度渲染。在The New Yorker、Path等网站中,均使用了这个方案,它可以使webkit内核的浏览器字重表现一致。(使用了次像素平滑之后,字重普遍比灰度渲染之后的字体重,效果详见携程的这个DEMO)。
  • Hinting技术:在打包的Webfont字体中加入Hinting,有助于Windows的小字体显示效果
  • 字重兼容性:出于兼容性的考量,不要使用font-weight的数值形式,也不要在@font-face里指定相应的font-weight数值,可以通过@font-face里定义的字体名来区分字重,如Gabriela-LightGabriela-Regular

此外:

  • 小字重字体(W1,W2)的小字号、大字重字体(W6以上)的小字号在win xp下的显示很难正常和好看,可以避免使用
  • 在webkit核的字体显示有问题时,可以使用如-webkit-text-stroke的hack解决问题,详参How to fix the ugly font rendering in Google Chrome

接口不健全,各个终端表现不一,这基本就是现状了。Mockee的关于字体渲染的ppt里说到:“接受现实,假设最坏的情况,等待未来新标准、新实现。”

关于@font-face加载成功之前的字体空白显示问题

如果LZ说的是@font-face的话。这个问题确实是存在的,如何解决呢?

沙渺在这里探索了一下字体预加载的方案,里面遇到的困难已经阐述得很详尽了。

目前为止,比较靠谱的方式是:使用webfont loader,在字体加载成功的回调函数中再应用相应的font-family的CSS样式。

字体转换的原始字体的相应区别

我刚才咨询设计师,他说,“可能有些非常细微的参数不对等吧”…… = =

这种问题可能做字体搞排印的才会明白。这方面的问题建议提到知乎上,然后@梁海或者其他这方面的人。


下面的内容是font-face的fallback问题的一个复现方式,给那些没有见到过这个现象的人……

用chrome看看这个DEMO吧:

http://jsfiddle.net/humphry/d86WC/

在这里我使用Fiddler将对woff的请求后的response捕获,捕获之后,由于对于浏览器来说,这个请求一直没有返回,我们可以看看此时的结果:

将捕获的response返回,得到这个结果:

可以看到,在.sample { font-family: 'Gabriela', serif; }中我们设置的serif的fallback没有在加载过程中出现。

因此,@font-face加载成功之前的字体空白显示问题确实存在,浏览器没有按照我们想象的,在@font-face加载成功之前使用fallback字体,在@font-face加载成功之后换用@font-face定义的字体,起码chrome不是这样。