04月09日
CODING 技术小馆 | 前端美学 · 字体排印的道与术

本文为 墨刀资深前端开发 陈奕钧 在 CODING 技术小馆 · 上海站 的演讲内容整理。

大家好,我是陈奕钧,来自台湾,目前在北京工作,在墨刀担任前端开发的职位,同时也是 W3C 《中文排版需求》的编辑。我在 2011 年开发了一个名为“汉字标准格式”的网页排版框架,也由我迭代、维护至今。今天想跟大家聊聊在 UI 工程领域常常被忽视的环节——字体排印。

字体排印是英文 typography 对应的中文翻译,当然也有其他翻译,我们今天使用“字体排印”这个名词。字体排印指调整版面还有文字的各种属性,在物理的媒介上向读者呈现可变并且易读,甚至更具吸引力的文本的技艺和学问,有时候称之为字体排印学。

图片

我们可能会疑惑,为什么要学字体排印?这不应该是设计师的职责吗?跟我有什么关系呢?身为 UI 工程师,我们每天都跟文字打交道,但是经常忽略了它的重要性。2006 年的时候,开发了著名的 Markdown 编辑器的 iA Writer 工作室的 Oliver Reichenstein,发表了一篇名为 <Web Design is 95% Typography> 的文章——网页设计是 95%的字体排印学。这篇文章转述了 1969 年瑞士著名字体排印师 Emil Ruder 的说法:今天的我们被淹没在海量的信息中,我们无法将这些庞大的信息吸收,字体排印师的职责就是把这些资料分门别类,并且转印成一种版式,让读者在茫茫的书海中能更容易地找到自己需要的讯息。把“字体排印师”替换成“设计师”、“UI 工程师” ,是不是觉得这句话也能精准描述 2018 年的 IT 行业的情况——95% 的 web 设计就是字体排印。甚至我们可以把 web 去掉,不管是书籍、路牌、印刷的、屏幕上的,都是跟字体排印相关的。

在 50 多年后的今天,我们虽然经历了彩色电视革命,有了影片、音频、博客甚至直播,在网页上放张图片也轻而易举,但文字仍是今天的主流信息媒介最重要的一种形式。一个好的 web 设计师知道怎么跟文字协同工作,他们视文字如同界面,也就是我们 UI 工程师要做的。

文字有着低传输需求和高信息密度的特性,可以方便我们重复的查看。在《哆啦 A 梦》的记忆吐司被发明出来前、在我们从智人变成智神之前,我相信文字和阅读都会从人们获取新知中扮演重要的角色,因此将文字妥善的展现给读者和用户,仍是我们重要的课题。

UI 工程师的自我修养

今天在座的各位都是 UI 工程师,我们的工作除了让界面加载的更加快速,让用户体验更加流畅,代码拥有可维护性以外,实现易用美观的界面也是工程师的职责,我认为要实现美观易用的界面必须要具备以下两种能力:

第一,看懂设计师的设计稿。盖房子的时候,建筑师有再好的想法,如缺少一个合适的、理解其图稿的建筑团队来执行计划,再好的建筑也只存在于纸上。一个视文字如界面的 web 设计师,也必须搭配得以理解其理念的工程师,才能实现他心目中的美好设计。怎样看懂设计师的设计稿呢?我们墨刀开发的最新“标注”功能,可以让设计师把设计稿上传至墨刀,为每个页面加上交互,再分享给 UI 工程师。UI 工程师可以看到页面上每个元素的坐标、尺寸、字体、交互效果等各种参数,也可以下载各种分辨率的切图。如果对设计稿有疑问,可以直接在不解的地方加上评论,并 @ 设计师,可以快速跟设计师沟通,又不用离开座位,大大减少沟通成本,简化开发流程,帮助我们达到“读懂设计稿”的境界。

UI 工程师还要具备字体排印的鉴赏和实作能力。有了这两种能力,UI 工程师才能良好地与产品、设计团队沟通和协作。曾经在纸张盛行的年代,媒介较为可控,出版方可以自由选择纸张的材质、尺寸来符合内容的要求。在今天的信息时代,我们有了荧幕,必须根据目标用户所用的荧幕种类(手机/平板/电脑/电子墨水……)和尺寸、解析度、平台对排版特性(CSS)的支持程度、预装字体的数量等多种因素来提供最佳方案。身为 UI 工程师的我们,才有能力在设计稿和成品间做出各种各样的权衡和取舍。我们 UI 工程师就是字体排印师。

# 字体排印入门

下面给大家讲一下字体排印的入门。第一步叫做分门别类。我们应该以用途来命名、分类,并使用语义化的标记语言,除了可以做好视觉方面的字体排印,更可以为软件提供基本的无障碍亲和力设施。在过去的铅字印刷时代,排字工人只要管控好我们的视觉媒介即可;但在信息时代,电脑不再是明眼人的专利,我们应在听觉、触觉上,为不同需求的用户提供同样不打折的、具有亲和力的服务。做面向一般消费者的产品的时候,分门别类用语义化的标记语言,用语义化的 class 来为文本做分类,比如提供给盲人使用的浏览器,也能够很好的为盲人服务。

第二步应该深入理解 CSS 中的继承概念,避免无谓地重复定义样式属性,以求代码的可维护性。可能十个 UI 工程师,有九个都很讨厌 CSS 的继承设计,对于选择器的分数权重也难以理解。但 CSS 在语言层面已经定型了,与其用一堆奇怪的方法论来躲避继承,不如好好学习并理解它,了解怎么在需要时覆盖或重置样式。

第三步是理解字体排印的四个方面:字、体、排、印。

关于字体排印——“字”

图片

“字”就是文字的字,与文字相处的最基本原则就是不要写错字。不要小看写错字这个事情,在出版门槛民主化的今天,人人都能发布网页、App,甚至出书。错字或标点、错误的拼写、乃至错误的大小写,也愈来愈常见。

原则上,一般名词在句中全小写,在句首则首字母大写。跟大家分享一句名言:“Case 不是小 case。”这里的两个 case 分别指不同意思。句首的 case,是普通名词,表示“大小写”之意,因在句首,所以首字母大写;在句中的 case,也是普通名詞,表示“事情”之意,但因为在句中,所以应该小写。原则上,专有名词在任何时候首字母要大写,苹果的 App Store,A要大写。我们要遵从名从主人的原则,比如 jQuery 或 iPhone,就有特殊的拼写形式,不应随意拼写。字体排印的字,还体现在要使用正确的标点符号,比如说“《安妮的日记》很有意思”这句话,如果我们把书名号去掉,就会让读者产生你偷看了安妮的日记的误解。再比如“魔戒可以让人隐形”,如果给“魔戒”加上书名号,会让读者感觉是魔戒这本书让人隐形。

字体排印还体现在本地化上。翻译成外语时,需要注意专有名词的选用,确认语句流畅通顺、文法无误没有语病,并且最好由母語者做一次 proof reading 校对。比如提供法文的网页服务,最好请一位法语母语者来做校对。这样才能确保文案和界面没有错字、语义顺畅没有歧义、翻译准确没有漏洞,使用一致的专有词汇,网站的专业度能大大提升。我们作为 UI 工程师,平时少有撰写文章的机会,但在每次机械性的复制粘贴文案的时候,我们仔细多看一眼,就可以减少很多产品本身的问题,与产品部门沟通时也能减少许多问题。

在技术层面上,我们需要注意正则表达式的问题。Unicode 最初被发明时,希望在二的十六次方个储存空间中(16 个 0 或 1),塞下全世界所有的文字,上限是 65535 个字符。我们现在称作 BMP,基本多語言文字平面。 最后当然事与愿违,光是台湾的研究单位,便整理了近十万个汉字,还有中日韩越等各个地区的汉字。现在每年 Unicode 都会更新版本,除了加一堆 emoji 外,也会有其他语言追加的字符。这些新字符大多收录在 BMP 之外,在 ES5 前的年代,我们必须使用代理对(surrogate pairs)的方式才能匹配到这些字符,甚至某些老牌数据库也不支持 BMP 外字,需要用特殊的方法才能让用户输入、显示 BMP 外字(所以有段时间,很多网站和 App不支援 emoji)。当时,汉字标准格式为了匹配 CJK 汉字,正则表达式是这么写的。

图片

我自己做开发时,为了要匹配到 Unicode 里所有的汉字必须这样写,这是 1.0 的年代,每年都会发布新的版本,每一年都会有新的区段,到了前两年大概有中间这段这么长。显然,每一年都要更新一次正则表达式,而且变得更长,是件很不合理的事情。好在 ECMAScript 6 有了新的 u 修饰符,用以正确处理四个字节的字符,还有提案中的“p 修饰符” Unicode 属性转义,我们可以用字符的属性来匹配,而不必再以码位和区段来匹配,这使正则表达式更加易读。目前 p 修饰符还在提案阶段,u 修饰符虽已是标准,但浏览器支持程度不一,我们可以用 Babel 插件「@babel/plugin-proposal-unicode-property-regex」来转译相应的代码至 ES5 格式。汉字还只是其中一小部分,拉丁字母、希腊字母、西里尔字母,甚至还有日本的假名、韩国的衍文的匹配也都有许多需要注意的地方。

关于字体排印——“体”

图片

接下来说到字体排印的“体”。西文主要有四种字体类型,衬线(serif)、无衬线(sans—serif)、手写(cuisive)、等宽(monospace)。汉字也有四大字体,宋体、黑体、楷体、仿宋体。苹果前两年的发布使用了新的汉字字体,为了跟以前的版本做区隔,就用了方体,其实就是黑体的意思。CSS 提供了良好的字体回退机制,让工程师只需要指定字体基型,不必知道特定的字体名称,如此一来,便能兼容各种作业系统。我们写 CSS,在 CSS 当中指定字体的时候,除非有特殊的需求,至少应该使用一种字体组,应该放在指定字体的后面,这样才能让浏览器做比较好的向后兼容。

Sans—serif 对应黑体,serif 对应宋体,monospace 对应仿宋体,cuisive 对应楷体,那么我们经常在网上看到汉字的宽字体,是怎么回事?汉字有着等宽的特性,所以当我们说,这是一个等宽 CJK 字体时,其实是指这个 CJK 字体的西文字符是等宽的,并且多数情况下,每个西文的宽度等于一个汉字的宽度。要注意这里的宽度仅仅是一种排版或编程显示需要而刻意赋予的“展示属性”,不代表一个汉字字符的储存和传输是西文字符的两倍。传统上汉字不使用斜体。在西文中,我们通常称呼为“斜体”的“italic”这个概念其实应该翻译为“意大利体”,相对于正文字,有些微的倾斜角度,带有手写风格,是一种手写体。意大利体在西文排版中应用在许多体例,比如书名、船名、长文引用、描写梦境、强调……等。
当我们对汉字调用“斜体”这一特性时,一般的排版引擎会用图形算法将汉字摆斜。由于没有字体设计室的直接参与,效果往往差强人意,我们一般称作“伪斜体”。当代的中文网页——也许是本地化时不够仔细,也许是对细节的不够重视——经常会出现伪斜体滥用的情况,我们应该用正确的格式和样式来替换这些斜体。比如书名应该使用书名号、船名没有特殊格式要求则用正文字体即可、长文引用或描写梦境可以使用楷体或仿宋体,强调则可以使用楷体来表示或加上着重号来突显。汉字标准格式为以上的种种情境都做了完善而精良的处理,有很好的参考价値,有兴趣的朋友,可以前往了解一下。

关于字体排印——“排”

字体排印的“排”就是排字的意思,用文字组合、排出合适阅读的版面。十至四十个汉字是我个人推荐的行长范围,少了显得零散、多了则困扰读者的眼球。1.25 至 2 倍字号是我建议的行高区间,小了拥挤、多了则显得散漫。正如前面所提到的,汉字有着等宽的特性,我们为文字段落区块(传统上称为版心)设置其宽度时,应该使用字号的整数倍,让汉字和标点一个接一个排好,文字在纵横方向上都能有序对齐,字间没有散乱的间距。还有就是标点规则,把标点符号排对很困难,经常有很多大牌网站也没有把这件事情做好。

图片

比如说以这个电视剧截图为例,是一个直排的文字,逗号的位置有点尴尬,不应该放在文字的左下角,应该放在“爱”的右下角才是正确的排法。“来的刚好”也是错的,“来”是一个动词,应该要用双人旁的“得”。还有书写方向,传统上,汉字由上至下,由左向右直排,但因为汉字有着独立成形的特性,改用横排是件很简单的事,某些情况下用到直排,要注意不要排的由左至右,这样会显得很不专业。

关于字体排印——“印”

最后是字体排印的“印”,此处的“印”不一定特指“印刷”,可以更广泛地用“呈现方式”来解读。比如说 Windows 的“开始菜单”不写菜名,“卷轴(滚动条)”也不再被人们拿在手上卷,Python 的 print 函式也不是真的要用打印机打印,语言会随着时间的变化拥有新的含义。如前面提到的,在信息时代,必须要根据目标用户所使用的屏幕种类、尺寸、分辨率、平台排版的支持程度以及多种因素提供最佳的方案。“印”所指的“呈现方式”即此。呈现方式的不同,是不是 Retina 屏幕、设备的可展示区块的大小和距离用户眼睛的远近,都是我们所要考虑的问题,影响著我们的设计决策。

前两年 Google 和 Adobe 公司合作的泛中日韩字体项目做了两个汉字字体,“思源黑体”和“思源宋体”,可以说是第一款现代的中文字体,有极粗到极细等多个字重。在 Retina 屏幕上,各种字重都能为设计师依需求自由使用;但在非 Retina 屏幕上,受制于像素颗粒的大小和字体渲染,文本使用小字号编排时,部分字重会显示得较为模糊甚至难以分辨,此时我们便应该调整文字尺寸或字体字重,来改善视觉体验。

字体排印有四个层面,可以说是相互分离又相互影响,需要设计师和 UI 工程师(aka 字体排印师)的用心处理,方可制作出优雅舒适的界面和阅读体验。

今天我的分享就到这儿,谢谢大家。

扫码关注 扣钉CODING 微信号,获得 CODING 技术小馆和产品更新 第一手信息。
图片

coding3431

1条评论

竖排汉字处理好了很美观,处理不好就很奇怪了

zhangzan6 个月前回复