设计师应该关注的一些字体排印技术

头图来自 Type Terms

最近的项目让我有机会重新梳理了一下字体排印相关的知识,决定把这些知识点整理下来方便日后查阅。这里所说的技术不仅指代码实现技术,也有字体排印方面的技巧、习惯等。相信这篇文章及里面链接的延展阅读能够帮助你全面的了解字体排印方面的知识,希望这篇总结能够帮到对此感兴趣的设计师。



文字渲染

我们知道同一个网页在不同机器、不同浏览器下的视觉表现是不一样的,说明影响文字渲染的因素有很多。那先来了解一下,一段文本是怎么在页面中呈现出来的。简单来讲,文字的渲染过程是这样:

1 编码/解码。文字集合会以一种编码方式存储,它规定了集合中每个字符对应的编号,为了实现在一份文档中可以正确显示所有类型的字符,于是Unicode 的编码方式诞生了,我们常见的是 utf-8 是 Unicode 的实现方式之一。你可以在Chrome里右键“检查”、并在打开的开发工具左栏前几行查看 HTML 的 head 部分,会看到类似 charset=“utf-8”的标签。浏览器收到服务器的内容后解码,会把这些内容转化为可阅读的文本。你可以在这里查询每个文字对应的编码,例如“雪”字的编码是&#x96EA。



2 选择字体。解码后需要选择字体来显示。这个时候浏览器会看 css 代码中font-family 指定的字体,按顺序去检索系统有没有这种字体,有的话就用指定字体显示,没有的话浏览器会用自己默认字体来显示。浏览器默认字体是可以手动设置的。为了最大限度还原设计,网站在设计时需要考虑不同系统、不同浏览器的字体表现,并写出合适的 font-family,这个后面会细说。

3 系统引擎处理。字体选择后不同系统有不同的排版引擎来处理文字,从而导致了文字在许多细节上表现不同。Mac OS X 使用 CoreText(Quartz) 渲染引擎,Windows 使用 DirectWrite 或 GDI。苹果和微软对字体渲染的总体态度有所区别:

Mac OS X 的字体渲染强调忠实字体设计,最大化保留字体的外形。边缘平滑是为了更好地传递字体设计中的曲线等细节,而小字号时显得模糊也是在此方针下的妥协。
Windows 的字体渲染强调文字的锐利和清晰。在操作系统介面和网页正文等小字号的地方比较清晰,但大幅牺牲字体的原貌。
GDI 分为 GDI Grayscale 和 GDI ClearType。前者为灰阶渲染 API,后者是亚像素渲染 API。由于 GDI ClearType 并未对字体进行垂直方向的平滑,因此当字体较大时会出现边缘不平滑的情况。为了弥补 GDI ClearType 的不足,MS 实现了 DirectWrite API,它在 GDI ClearType 的基础上增加了垂直方向的平滑。

从左到右:理想形状、黑白渲染、灰度渲染、亚像素渲染。(图片来自网络)

排版引擎会输出不同的渲染策略,一般的渲染策略包括:黑白渲染、灰度渲染、亚像素渲染。现在主要是后两种。从视觉感受上来讲,灰度渲染文字会更清秀一些,亚像素渲染由于边缘有暖色和青色,文本看上去会稍暗,不能够还原设计。亚像素渲染的使用是为了让文字看上去更平滑,但是随着 PC 屏幕越来越高清,会逐渐失去作用。事实上手机上基本使用的是灰度渲染,因为像素密度够高,字体容易平滑,尽管可以通过设置开启亚像素渲染。

4 浏览器引擎处理。操作系统提供了支持不同的字体渲染方法的 API。但是字体渲染的 API 都是由浏览器厂商自己选择的。所以同一个操作系统,不同浏览器看同一个页面,字体的视觉表现也会不一样。

5 光栅化。字体大都是矢量的,经过渲染引擎处理后最终要以像素点阵呈现在电脑屏幕上。这里会涉及 hinting 的技术。hinting 是一种字体渲染提示信息,作用是让光栅化的文字落在正确的像素上。在低像素屏幕上显示小字号文字,由于可供显示的像素格子不够多,像素落在字体轮廓的具体哪个像素点上对最终成像影响极大,因此需要有一个规则来指导。同样,这种技术随着屏幕像素密度不断变大,可能最终会消失。


图片来自网络

关于灰度渲染和亚像素渲染多说一点。Mac OS 是默认开启亚像素渲染的(应该是在非 retina 屏幕上),而 iOS上的文字渲染默认是灰度渲染,关于原因在知乎上有一些讨论。首先手机像素密度比较大,亚像素渲染没有太大必要,另外亚像素渲染需要更多计算量。我个人是不喜欢亚像素渲染的,它让文字变得暗淡浓稠。

有一种特别简单的方式在页面里去掉亚像素渲染。Chrome 里审查元素,在右侧栏 css 顶部“element.style { }” 里插入 “ -webkit-font-smoothing: antialiased;” 这个属性你会看到文字视觉感受发生了变化。并不是所有浏览器都支持这个属性。



字体选择


· 字体格式

我们常常看到字体格式主要是两种 .ttf 和.otf,即 truetype 和 opentype,粗糙的来讲,opentype 是 truetype 的升级,能够容纳更多的字符集。还有另一个常见的词是 Postscript,它是一种描述字体曲线的技术。关于字体格式这里有更多的知识点


· 客户端的字体选择


通常客户端的字体不需要选择,跟着手机系统默认设置走就好了。iOS 9 之后默认中文字体 Pingfang,有 6 种字重,英文和字符部分字体是 SF UI。苹方相比之前的华文黑体略显圆润,刚开始大家还都不太习惯,嚷嚷着安卓化了,现在看来这套字体表现不错,字重比较多,细体还比较优美。有一篇文章总结了 iOS 字体演进的历史可以看一下《Mac OS / iOS 六年字型战争》,这篇文章里花大篇幅鄙视了华文黑体设计上的各种问题。Android 默认中文字体思源黑体 Source Han Sans,虽然设计上有七种字重,但是好像在实际应用中只能选择两种字重?且这两种字重很难令人满意。需要说明的一点是,Source Han Sans 是 Adobe 的称呼,在 Google 的体系里是 Noto的一部分。Android 默认英文部分 Roboto,表现个人觉得不错。

iOS 里的 App 除了应用默认字体,也可以动态下载 Apple 提供的一个字体库中的字体,另外也可以将需要的字体打包在 App 中。将字体打包在 App 中加大了体积、同时可能涉及不菲的版权费,所以除了一些阅读应用很少这么干的。

对于 Android,App 内嵌字体同样也很少见,思源黑体,说实话显得有点笨拙,我是不太喜欢的。Android 的好处在于很多厂商会自定义系统默认字体,比如 MIUI 的小米兰亭在兰亭黑的基础上做了小优化、锤子的 Smartisan OS 用的是冬青黑,视觉上表现会比原生好很多。



· Web 的字体选择

Web 上的字体选择要灵活的多。无论 Mac 还是 Windows 系统都内置很多中英文字体,通过 css 调用比起客户端的处理简单的多。当然每台电脑的字体库可能存在差异,font-family 需要照顾到很多情况。那如何写 font-family 最优雅呢?链接里有些讨论,主要是两种思路,一种思路是考虑 fallback,能尽量还原设计,根据不同系统上表现比较好的字体按照一定顺序写进去。另外一种思路是简单处理,让 css 指向系统默认字体,比如这样的设置 “font-family: sans-serif;”。我个人是倾向于前者的。

来看看著名字体博客 Typeisbeautiful 的字体设置。因为是独立站点,它在英文部分使用了比较个性化的字体,然后可以 fallback (字体回退)到比较常见的 Helvetica,而 Arial 的设定显然是考虑 Windows 系统;中文部分冬青黑是首选,其次才是苹方,这可能是设计师更偏爱冬青黑一些;设计师在最后写了思源黑体,估计是考虑到一些Android设备上的应用。

font-family: “Classic Grotesque W01”, “Avenir Next”, “Segoe UI”, “Helvetica Neue”, Arial, “Hiragino Sans GB”, “PingFang SC”, “Heiti SC”, “Microsoft YaHei UI”, “Microsoft YaHei”, “Source Han Sans”, sans-serif;

有一点必须要强调一下,font-family 里,英文字体需要写在前面,避免页面中的英文部分使用中文字体的英文部分,那样会遇到不少问题。

这里顺便说一下字体设计。黑体确实是很难设计的,除了字形、美学设计,界面字体设计面临很多技术上的问题,且中文字体涉及到大体量的字库,因此到现在来看,市面上被公认还不错的阅读黑体可能就说得清的几种:微软雅黑、兰亭黑、冬青黑、信黑、思源黑体… 事实上大部分人分不清字体,一些字形相近的字体确实连设计师也辨别不出来,比如著名的 Helvetica 和 山寨版 Arial,它们只能通过部分字体的线脚切口方向辨别出来;比如很少人知道方正兰亭黑和微软雅黑是兄弟字体,它们的差别只有部分线脚长度和其它特别细微的差别。在字形差别“不大”的情况下让普通用户辨别那种字体更好也是很难的一件事情。尽管如此,选择好的字体是很有必要的,好的字形、优秀的技术方案,能让用户在长时间阅读的过程中体会到阅读带来的舒适和愉悦。



· Webfont

Web 上的字体使用比客户端灵活的另外一点是 webfont 的应用。简单来讲 webfont 指的是通过 @font-face 语法调用存贮在线上的字体文件并加载到用户本地打开的页面,避免因用户本地字体缺失导致的设计不能还原。理论上来讲它可以让任何页面调用任何想要的字体。但是实际中中文 webfont 很少被用到,主要因为是一个中文字体好几兆,加载太慢,而且 UI 界面中常规的本地字体能够满足需求,另外,线上开放版权的中文优秀字体还是太少。目前 Google家Adobe家都有比较好的在线字体库,而国内也有一些网站在致力于中文 webfont 的应用,比如有字库字蛛 等。

webfont 最常见和最实用的是 iconfont。将 icon 导出生成成一套字体文件放在线上,方便调用和管理,能够灵活的用 css 控制 icon 的大小、颜色,比起图片占用空间也小很多。推荐国内的在线管理工具 iconfont.cn



字体排印的一些要点


· 可读性


图片来自 typeisbeautiful

字体排印除了美观,最为注重的是信息呈现的效率,或者说是可读性。影响文字可读性的因素包括字型设计、衬线非衬线、字号、间距、颜色等等,这方面的文章很多,不多赘述。基础可看《字体设计基础》《关于文字的可阅读性》

影响阅节奏感的的因素主要是字号、行间距、文本宽度。网上有很多讨论最合理的搭配,但事实上应该没有放之皆准的法则。先说字号,web 上正文字号不低于 12 是一个通用的原则,辅助文案可以稍小点但也别小于 10 号,现在 web上的字号有越来越大的趋势,但个人觉得不要大于 18 号的好;舒适的正文行间距在 1.4–1.8 之间,字号越小行间距应该越大;文本宽度,视字号而定,一般控制在 500–700px 之间,原则是不要太短而频繁换行影响阅读效率、也不要太长而容易串行。

从字体的可读性来讲,传统的理论认为宋体更适合作为正文字体,因为衬线的变化识别性更强、更舒适,而黑体粗壮适合作为标题。放在西文环境里面可能是这样,Medium 网页版也是遵循这样的原则。但是,现在来看中文环境的互联网页面,极少正文用宋体的,为什么呢?我的简单分析是,1 黑体更现代,且能跟页面上其它元素更和谐,宋体气质上太古了,除了纯阅读产品,不太好用。2 现在的宋体字体,极少有多重字重的,排版设计不够灵活,做一些加黑强调之类的属性时显示效果不佳。3 中西文混排时效果也不佳,中文衬线字体跟西文非衬线字体放一块显然视觉张力不一样,感受不均匀;但又因为衬线字体的字形都是比较独特的,中文衬线字体跟西文衬线字体也很难找到合适的搭配。为了省事,干脆统一用黑体字好了。



· 对齐方式、自动断字

页面文本的大部分时候采用的是左对齐方式,两端对齐也会有所使用。左对齐最大的问题就是右侧会参差不齐,对文本的整洁性有些影响。因此一些网站会采用两端对齐(齐头尾,justify)的方式强制两端对齐、字符间均分多余的空白。如果是纯中文文本,在行宽够大的情况下不同行之间的由于均分空白造成的字间距的不同可能不那么明显,但是在英文文本中,齐头尾很容易产生字符间距过大的情况,尤其是在英文没有处理“自动断字(hyphenation)”的情况下。因为在现在的中文环境下英文混排的情况太多,齐头尾必须配合自动断字效果才可能好。但并不是所有浏览器都支持 hyphenation 的,并且据说高质量的 justify+hyphenation 会大大增加计算量,所以一般情况下左对齐还是首选,除非对自己的排版算法比价有信心。这里有一些关于对齐方式的讨论值得看看。



· 缩进

关于段首的处理,有缩进、不缩进和首字母下沉等处理方式。后者现在已经不多见了。段首缩进本质上是为了让分段看上去更明显,但是它会让页面变得不那么整齐,尤其是在一个页面内容模块较多的情况下会显得更乱。如果能够设置合理的段间距和行间距,能够让分段看上去比较明显,不缩进在 web 排版中显然是更好的方式。



· 标点符号避头尾

中文排版有一个比较简单但是却被很多人忽略的排版规则就是“标点符号避头尾”,让逗号、句号等标点符号出现在行首实在是让人不能接受。至于详细的避头尾规则,可以看 wiki 的解释



· 标点挤压

标点挤压简单的说是处理一些相邻标点间距、行首尾全角标点空间的规则,能够让文本在行首尾对齐和标点空间更加合理。看上图就能明白。标点挤压是很有意义的一个排版规则,但是在 UI 界面却基本看不到使用,这是由于现在的浏览器和 css 语法并不能很好的直接支持,需要一些高级代码才能实现。 网上有一些人在这方面进行了尝试,比如“汉字排版格式”这个排版框架,但这种框架应用于 Web 端,有没有移动端的类似处理还没有发现。

Ai 和 PS 等软件能很多好的处理自动断字、标点符号避头尾和标点挤压,并预设了一些规则可供快速调用。

关于这几个排版规则 Adobe 叫做“ CJK 字符排版”,有详细的说明文档,在此也不多说了。



· 中英混排

中文英文数字混排,中文和英文、数字间应该有比较好的空隙,让文本更易阅读、语言切换有节奏,视觉上更舒适。比较专业的排版软件如 Indesign 等能够比较好的处理中英混排的间隙,但是在界面中我们通常只能依靠用户自己手动键入一个半角空格来实现比较好的间隙。


但其实前端和后端技术上都能够实现让文本自动在中英文之间加入空格,比如这个特别有意思的 Chrome 插件“为什么你们就是不能加个空格呢?”,能够自动处理空格,但这个还是处理得有些简单了,很多地方有些问题。事实上雪球在一个项目里也尝试过通过后端来处理所有文本的中英文空格,并过滤掉一些链接类似的地方,内测的效果其实挺不错,但是,最终我们还是没有上线这个属性,因为一些违背用户习惯的地方得不到很好的处理,比如专属名词“万科A”,如果处理成“万科 A”就会显得比较奇怪,虽然理论上能够比较高成本的过滤掉大量的专属名词,但还是可能有一些处理不到的地方。中英混排到底哪里该加空格这里有一些比较好的讨论可以看看。



· 基线和行高

西文字体是有明确的基线概念的,即以 X 底部为字体基线,作为纵向对齐标准。中文字体因为是方块字,没有明确的基线概念,但是因为涉及中英混排时与西文的纵向对齐关系,事实上形成了一定的基线标准。关于这个问题,这里有些讨论值得看一下。

图片来自 Adobe


行距、行间距、行高、文本高度,这几个词经常被人混淆。中文中可以这么理解“行高=文本高度+行间距”。但在西文中文本高度比较模糊,行高指的是基线到基线的距离。在 css 中通过 line-hight 这个属性调整行高,可以用倍数,比如 1.5em,也可以写绝对值,比如18px。


这里需要说明一点工作中遇到过的一个问题:因为大部分字体都会有默认行高,比如14号苹方,默认行高是 20,如果此时在客户端代码中直接写 1.5 倍得到的结果行高是 30,但其实我们想要的是 21 这个行高,所以如果用倍数关系,需要在此之前清掉默认的行高。



· 字重

UI界面中,大部分时候只需要两款字重,regular 和 medium,分别用于正文和标题。比较现代一点的黑体都是拥有多重字重的,但不一定能在实际开发中应用,像前面提到过得 Android 思源黑体。css 中设置字重也有两种方式可选,比如 font-weight:bold 和 font-family:“Helvetica Neue Bold”,常见前一种。



字体排印的一些习惯


· 直角引号和圆角引号

近几年看到大量直角引号(「」)的应用,很多人呼吁将圆角引号(“ ”)替换成直角引号,知乎上有大量类似的讨论。为什么这个问题会引起大面积的讨论我刚开始并没有弄太明白,只觉得那些说方角引号更好看的论据站不住脚,况且国家《标点符号用法》中明确规定了横排时用圆角引号、竖排用方角引号,输入法和键盘也不能很好的支持方角引号的输入。后来看到有人讲到 Unicode 编码时中文引号和西文引号共用编码,因此在网页技术中,如果 font-family 高优先级指定了西文字体,中文中的引号会被解析成半角引号,造成中文中夹杂半角引号的不规范问题,而直角引号有自己独立的Unicode 编码不会出现这样的问题。再加上方角引号在借鉴西文标点符号规范之前早已存在,似乎全面使用方角引号也是可以的。但是,这个事情就跟现在的键盘也不是打字效率最高的布局方式一样,无数的用户已经形成了输入圆角引号的习惯,无数的输入法也不能快捷支持输入方角引号,所以要想全面推进是很困难的,何况 Unicode 也有可能有优化这个 bug 的一天。从我个人来讲,也并没有觉得方角括号在视觉上更为舒适,反而觉得会有一种倾斜了引号中文字的感受,但是考虑到网页中圆角引号不能显示全角,也会尝试下使用直角引号。



· 中文斜体


中文能不能用斜体?能。在 UI 界面设计中的一些辅助文案的地方用斜体可以起到一定的强调和装饰作用,但是在正文中大量用中文斜体是不恰当的做法,因为基本上中文字体本身都没有设计斜体字形,页面中看到的斜体中文是浏览器强行倾斜后的结果,属于伪斜体(oblique type),而不是字体的斜体字形(Italic type)。中文因为笔画比较复杂,强行倾斜后会导致一些笔画变形,造成可读性降低、视觉也不够美观。



· 段首缩进

前面已经提到过了,段首缩进似乎没有成文的规范,有缩进两个汉字位,也有缩进一个汉字位,到现在其实大部分网站都默认无缩进。



· 连字符、破折号、连接号和短下划线

能够很好弄懂这几个符号使用规则的人不多,包括我自己。西文语境里关于前面三个这里有比较好的讨论和定义,在此就不多说了。短下划线(_)并不多见,主要用不一些不允许空格、但是需要分词的地方,比如在一些文件名和代码中。既然使用频率这么低那为什么不干脆使用连字符(-)代替呢?我没有找到比较好的解释,自己的理解是 hyphen(-) 在和分词方式(-)同时出现时视觉上是区分不出来的,为了强调不是连字而是分词,有必要使用比较明确的短下划线。有一点需要注意的是如果为了 seo,url 里最好不要使用短下划线(_)而是用连字符(-)做分词,因为 google 的规则只会把连字符当成空格。关于它的解释和用法这里有详细的说明



· 专有名词特定大小写

如果你把 iPhone 6s 写成 iphone 6S,把 iOS 写成 ios,那一定会被人、尤其是程序员鄙视,程序员也很讨厌吧 HTML5 说成 H5;同样的,如果你把 UI 写成 ui,设计师同样会觉得你不专业。这些习惯,在被虐几次后自然会好好遵守。



· 序号标点的使用

序号后的标点符号用全角还是半角,也是一个不被注意的地方。有一些简单的规则可以遵循,即序号后侧的标点是序号的一部分,应当跟随序号的属性。西文标点加半角空格然后接文字,中文序号用全角中文标点直接接文字。

这里还有一些总结的比较好的排版习惯可以延展阅读。

字体排印在很多地方只有习惯没有规范,比如直角和圆角引号之争。只要能够满足功能性其实都没有太大问题,但是现在有大量的没有美学的排版充斥在互联网里让人难以忍受,这些人可能还包括一些所谓的内容编辑、新闻人员等本应该对排版高度敏感的人群。互联网很浮躁,每天有太多标红、加粗、加大字的需求…



结尾

这篇文章基本是自己在工作中遇到的一些关于字体排印设计实现问题的总结,大部分结论来自于网络讨论的整理,并都附上了原文链接,有兴趣的朋友可以在此起初上延展阅读。这些总结基本上是基于 Mac OS、iOS 和 Chrome,其它操作系统和浏览器并未做充分验证。

需要说明的一点是,即使对这些知识有所理解,但限于技术、时间成本,以及与你合作的人是否跟你有同样的意愿去解决一些看上去回报不那么高的“细节”问题,很多好的字体排印处理方式都没法在项目中实现。好在,现在越来越多的人字体排印产生兴趣并参与讨论,国内字体设计厂商和科技公司也越来越给力,中文字体设计和字体排印应该会快速赶上来。

字体排印是设计中最基础的知识,在网络环境下也是非常复杂的,有许多规范和用户习惯需要考虑,设计师必须对用户环境和技术实现有比较好的理解才能做出好的文字排版,同时,有必要通过设计去影响和提升用户对于字体和排版的品味。

这篇文中的观点和结论难免会有疏漏和错误的地方,欢迎指出。到此只是一个阶段的总结,之后有更多关于字体排印的技术实现、规范和习惯相关的一些知识点会持续更新。

以上。

-----------------

雪球设计中心XDC,正在招募用户体验设计师,加入我们,一起让互联网金融变得有意思,简历投递 zhangwei@xueqiu.com

编辑于 2017-06-02 13:35