字距调整 (Kerning)

调整相邻字符间距的技法,根据字符组合实现视觉上均匀的间距。

字距调整 (Kerning) 是一种对相邻字符之间的间距逐对进行调整的排版技法。每个字符都有各自固有的形状,如果机械地等间距排列,就会出现某些组合在视觉上显得不均匀的情况。例如"AV""To""WA"这样的字符对,在默认间距下字符之间会显得过宽,因此需要收紧间距来整理视觉上的平衡。

字距调整的历史可以追溯到活字印刷时代。金属活字是通过让字符的突出部分 (kern) 叠在相邻活字的上方来调整间距的。在数字字体中,每个字符对的调整值保存在字体文件内部。保存位置有 2 种,一种是历史悠久的 kern 表,另一种是放在 OpenType 的 GPOS 表中的 kern 特性。带有 CFF (PostScript) 轮廓的 OpenType 字体在规范上无法使用 kern 表,其字距调整必须通过 GPOS 提供。因此,若以找不到 kern 表为依据判断"这个字体不带字距调整数据",就会读错。字体质量越高,定义的字距对越多,有时可达数千对。

在 CSS 中,可以用 font-kerning 属性控制字体内置的字距调整数据。值有 auto (由浏览器判断)、normal (启用)、none (禁用) 3 种。而 letter-spacing 属性是对所有字符一律追加间距,与字距调整是不同的概念。字距调整是针对特定字符对的个别调整,letter-spacing 则是整体字符间距的调整。

在日语文本中,调整标点符号和括号前后空白的"ツメ組み"(挤压排版) 相当于字距调整。日语的标点符号和括号被配置在全角宽度之内,原样排列时多余的空白会很显眼。使用 OpenType 字体的 palt (Proportional Alternate Widths) 功能,可以把按全角宽度设计的字形改用与其形状相称的宽度。在 CSS 中可通过 font-feature-settings: "palt" 启用。不过 palt 的作用对象并不只是标点符号和括号。按规范,所有按全角宽度设计的拉丁字母、汉字、假名和符号都是对象,而且它并不是把字形替换成另一个字形 (替换是 pwid 的职责),而是只替换字符的前进宽度。也就是说,一旦启用 palt,正文整体的字符步进都会改变,以全角 1 个字符 = 1em 为前提组建的布局,其宽度估算就会失效。是只对标题局部使用,还是正文也使用并重新估算宽度,请先确定其中一种再应用。

字距调整和字距追踪 (tracking) 经常被混淆,但它们是不同的概念。字距调整是调整特定字符对之间的间距,而字距追踪是对选定的整段文本均匀调整字符间距的操作。标题中加宽字距的追踪有时很有效,正文中通过字距调整所做的微调则有助于提高易读性。

font-kerning 的初始值是 auto,其含义是由浏览器决定要不要使用字距调整。有些实现会在字号很小时关闭字距调整,这是为了避免收得过紧而使可读性下降所做的判断。也就是说,并不能断言"只要加载了 Web 字体,字距调整就一定会生效"。对于设计上无论如何都希望生效的位置,应明确写出 normal;反过来,对于希望在不同环境之间统一显示宽度的位置 (例如根据字符数反推显示宽度的界面),则明确写出 none,不把判断交给浏览器,这样可复现性会更高。

从字符计数的角度来看,字距调整不会影响字符数本身,但相同字符数的文本其视觉宽度会发生变化。例如"WAVE"和"MINI"都是 4 个字符,显示宽度却并不一致。不过这一差异的大部分来自各个字符固有的前进宽度不同,字距调整只是在此之上叠加了以字符对为单位的增减。更本质的前提是,在比例字体中字符数与显示宽度并不成正比。若要把文本放进固定宽度的布局 (横幅广告、按钮、OG 图像等),比起用字符数决定上限,直接测量显示宽度本身更为可靠。在浏览器中,可以用 Canvas 2D 的 measureText 在保持相同字体设定的状态下取得宽度;对于已经绘制出来的元素,则可以用 getBoundingClientRect 读取实际尺寸。把字符数上限只作为输入框的参考值,溢出的判定则用宽度来进行,做这样的区分可以让布局更不容易崩坏。

分享这篇文章