有关字体的小小迷思
在前端工作中,大家都会时常需要注意到一些小小的细节的地方,虽然很小很容易忽略,但是却也直接到关系到用户体验的问题。
Q1: – 明明是微软雅黑,为什么在 MAC 下却变成了种丑丑的字体?
Q2: – 为什么微软雅黑的字有时候看着怪怪的,大小不一样呢?
Q3: – 为什么相同的页面在不同的系统不同的浏览器下看却是不一样的?
Q4: – 字体渲染到底跟什么有关系?
为此,做了一个小 DEMO 以测试一下,分析下相同的页面在不同的 OS 和不同的浏览器下的表现差异。
一、编码与解码
Web 服务器返回的 HTTP 头中的 Content-Type: text/html; charset=“”的编码
与 html 中“ lang ”属性有关
网页本身 meta header 中的 charset 部分
浏览器菜单里一般允许用户强制指定编码
注:chrome55已经去掉默认编码选项,改为auto-detect。
二、选择字体
按照字体的描述方式来分:
点阵字体
矢量字体(轮廓字体)
矢量字的好处是字体可以无级缩放而不会产生变形。目前主流的矢量字体格式有3种:Type1,TrueType 和 OpenType。如下图中,前面有两个 T 的是 TrueType 的格式字体,O 开头的是 OpenType 的字体。
很多人把“宋体”(simsun)当作点阵字体,其实不是,它和“微软雅黑”(microsoft yahei)一样,都属于轮廓字体,只不多12px~17px的宋体内置了点阵信息而已。
按照字体的表现形式来分:
衬线字体(serif):比如,宋体,Georgia,Times New Roman
非衬线字体(sans-serif):比如 Tahoma, Arial , 幼圆
其它字体:等宽字体(monospace),书写体(cursive),梦幻体(fantasy)
三、系统已安装的字体
首先系统所包含字体不只和系统预装的字体有关,还和系统上安装哪些软件有关。微软操作系统下,详细的系统和一些软件包含的字体可以查看这个索引:Microsoft typography,Mac系统可以查看这个索引:List of typefaces included with OS X,移动端 IOS Fonts 和 IOS Font List 。
A1: 由于不同系统默认安装的字体的不同,且不同浏览器默认渲染的字体不同,如果只在css里定义里,font-family:’微软雅黑’ 的话,在MAC里有些浏览器下没有相关中文字体定义的话,会回退到MAC下的默认宋体展示,视觉效果就会大打折扣了。
四、系统渲染引擎
不同浏览器有着不同的渲染引擎。Mac OS X 用户使用 CoreText 渲染引擎,Windows7 和 Windows Vista 用户使用 DirectWrite 或 GDI ,而 Windows XP 则使用 GDI。
GDI 分为 GDI Grayscale 和 GDI ClearType 。前者为灰阶渲染 API,后者是亚像素渲染 API。由于 GDI ClearType 并未对字体进行垂直方向的平滑,因此当字体较大时会出现边缘不平滑的情况。为了弥补 GDI ClearType 的不足,MS实现了 DirectWrite API,它在 GDI ClearType 的基础上增加了垂直方向的平滑。
使用同一颜色,感官上的颜色深浅为:黑白渲染> grayscale > sub-pixel。
iOS 和 Mac 的渲染引擎一样,但采用的是灰度渲染,默认情况下亚像素抗锯齿是关闭的,但可以通知设置开启。
由于渲染策略的不同,字母a在不同的浏览器和 OS 下的渲染表现也不同。第一个是理想模型的a,第二个是灰阶渲染的a,第三个是亚像素渲染,第四个是黑白渲染。
五、浏览器
常用字体在浏览器中的渲染情况
注:从 chrome52 开始,google 停止对于老的操作系统的支持,包括 windows xp 和 windows vist a停止了 GDI 的字体渲染,从而只支持 DirectWrite.
六、光栅化(hinting)
光栅化是将文字从一个向量表示(比如一个 TrueType 字体)转化到光栅或者位图表示的过程。在这个过程中往往涉及到一些抗锯齿技术来使得屏幕上的字体更加平滑易读。但是,号称100美元一个字的微软雅黑为什么会出现字体大小不一的情况?
A2: ClearType 的渲染方式,使得它非常依赖 hinting 信息。但是微软雅黑的 hinting 饱受诟病,特别是在小号字显示下,特别明显。
七、CSS 定义
CSS 对于字体的定义属性也有很多。比如 font-family,它的属性的值是用于某个元素的字体族名称或/及类族名称的一个优先表。浏览器会使用它可识别的第一个值。
字体系列名称中有两种,
第一种是指定的字体系列名称,比如:“times”, Arial”等。
第二种是通常字体名称,是一个字体族。比如我们习惯添加在 font-family 最后的 sans-serif 和 serif 。
A3: 从测试 Demo 中可以看出:字体的展现受系统预装字体的影响,也受浏览器默认字体的影响。Mac 下的中文字体,除了受 font-family 属性中的字体名称优先集影响外,也受最后一个属性 serif 和 sans-serif 的属性的影响。因此,如果你对中文字体只定义了微软雅黑,或者没有定义中文字体,并且定义了衬线字体,那在MAC下显示的就是图中的宋体。
不同的操作系统有不同的渲染引擎,但是即使是相同的操作系统,不同的浏览器也会有不同的表现。因为浏览器厂商所选用的渲染 API 都是不同的。
-webkit-font-smoothing属性:-webkit-font-smoothing: none | subpixel-antialiased | antialiased
none: 不平滑,字体具有锯齿锋利边缘,适用于小像素的文本。
subpixel-antialiased 使用亚像素平滑。
antialiased 使用灰阶平滑。
还有一些别的属性:
Github上的 font-family 是这样定义的:
1 | font-family:"-apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol" " |
那么这个 -apple-system 和 BlinkMacSystemFont 是什么呢?
-apple-system 用于调用系统默认 UI 字体,并且会根据 font-weight 声明选择恰当的变体。system 将来有可能成为标准,-apple- 为过渡阶段的厂商前缀。
BlinkMacSystemFont:为 macOS Chrome 应用系统 UI 字体,与上面等同。
结论:
A4: 从字体在浏览器上的种种表现来看,分析其原因,这和编码方式,系统字体类型及排版引擎,浏览器都有关系,是一种比较复杂的表现方式。小小字体在不同环境下的表现方式都是不一样的,要尽量识别他们的差异,并能找到一种最佳适合的解决方式。
参考文档:
1. 维基百科——计算机字体
https://zh.wikipedia.org/wiki/%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%AD%97%E4%BD%93
2. 网站字体渲染过程
https://isux.tencent.com/website-font-rendering-process.html
3. 字体渲染
http://ued.ctrip.com/blog/font-rendering.html
4. DirectWrite 简介
https://msdn.microsoft.com/zh-cn/library/windows/desktop/dd371554(v=vs.85).aspx
5. 在WEB内容中使用系统字体
https://csspod.com/using-the-system-font-in-web-content/
6.A Closer Look At Font Rendering
https://www.smashingmagazine.com/2012/04/a-closer-look-at-font-rendering/
本文地址:http://www.tuquu.com/tutorial/di3382.html