这一个空格非加不可吗?

我认为还有另一种得出相同结论的简单的思考是,在中文语句中穿插英文成分并不比这些情况更特殊:在中文中穿插数学符号或公式、穿插类似于说明书内容有时会用到的小图标等等。当我们认定写作的主环境是中文,便应把中文的主环境的书写习惯运用在每一个亚环境(英文、数学符号或公式、小图标等嵌入)以外的地方。而中文书写习惯里没有半角空格。

不知从何时开始,手动在汉字和字母间加半角空格竟然成了一种骄傲。

这句话出现在《一天世界》博文「‘Impossible things just take longer.’」中。如果使用中文写作并且在意排版,你也许也已经发现中西文之间需要一定空白才能达到视觉平衡——下面的图中同一段文字中用不同的中西文间空白排出来,视觉效果孰优孰劣一看便知。今天的大多数操作系统(几乎全部,但iOS 13+对此问题有所改善)和浏览器都没有能处理这个问题。于是今天的中文互联网下,一部分人已经养成在中西文之间手动输入一个半角空格(U+0020 SPACE [ ])的习惯,包括我在内。但我一直认识到这是在技术受限下的无奈之举,它甚至是错误的。今天已是我开始关注这个问题的多年之后,这个问题仍然没有一个最终的解决方案。

对比调整与不调整中西文间空白

问题是什么?

我相信不需要质疑的是,在中西文混排时中西文之间的字距(或者说空白,类似于西文排版的kerning)是需要的——上面的图示展示了这样做的优势,W3C也提出了这样的需求。那么接下来的问题是,这个空白应该从哪来?加空格是不是一个合适的手段?

我的简短回答就是知乎用户钱争予在知乎回答里的这句话:

不反对现有技术条件下手工加空格,但反对规范化或标准化之类。

大约2013年左右我看到这个知乎问题,其中这一回答已经对这个问题回答得很充分,也让我一直坚信把中西文间的半角空格视若圭臬是不可取的。在下面的讨论里我还想说一下我自己的推理、以及回应一些认为这输入空格才是准则的说法。

在我看来,这一问题就和「输入两个换行符来给段落添加段间距是不是可取?」或「在文本段落和图片混排的内容中,用换行符来给段落和图片间添加间距是不是可取?」很相似。对于前一问题,我的答案会是「如果在无法控制行间距的纯文本编辑器(例如Windows的Notepad或很多命令行工具)中,换行两次来加段后距无可厚非甚至可以成为一种整齐的办法;然而在如今的网页或可对段间距(段前距、段后距)进行控制的工具里,这么做显然很糟糕。」

我想,要认同这两个类比和我们讨论的问题是同样的性质,需要先讨论中西文之间的空白是所处什么地位。如果这一空白是排版需要而非写作习惯,这些类比应当可以成立。

它是写作问题还是排版问题?

中英文间的空白应是写作者面对的问题还是排版者(排版引擎)面对的问题?假如写作者是在全篇用英语写作,某个句子两个英文单词中间插入了一个中文词语,那么中英文的空白应该由谁处理的答案显而易见——写作者是需要加空格的。原因是这个空格作为词间空格,本身就是语义,是整个句子所用的语言(英语)书写习惯的一部分;而语义就是写作者要考虑的所有东西。但当问题变成写作者全篇都在用汉语写作时插入了英文,似乎就有很多人认为答案不那么显而易见了。

示例英语、汉语为主要行书语言时与其它语言文字的混排

上面英文写作的例子里,得出写作者需要加空格的根本原因是:词间空格本身是英语书写习惯里的语义单元。用同样的逻辑,只要回答问题:中文的写作者认为添加在中西文间的空白是有语义的吗?如果有,这个空白就是写作者面对的问题;如果没有,它就是排版者(排版引擎)面对的问题。

中文写作时空格有语义吗?

绝大多数情况下,空格不是中文行文的一部分。我知道的例外仅有

  • 用全角空格作为抬头来表示尊敬。在现代中文行文中已经非常少见;
  • 有些人有使用半角标点加半角空格代替一个常规的全角标点的书写习惯,比如文悦字库的厉向晨、知乎用户Testman等。这种中文行文习惯并非正统,但在这种习惯下,半角空格的被考虑成语义单元我认为是合理的,因此这样的写作者在中英文中插入空格在我认为也是可取的;
  • 对自己使用空格的语义有自觉的写作者所使用空格的情况。

因此,除非写作者对空格有特殊考虑,在绝大多数情况下中文写作习惯里不应存在空格,更不应存在和英文词间空格功能等同的空格。结合上面「它是写作问题还是排版问题」的论述,中西文之间的空白对中文写作者而言不应考虑,而应当交给排版引擎。

另一种思考:主环境和亚环境

我认为还有另一种得出相同结论的简单的思考是,在中文语句中穿插英文成分并不比这些情况更特殊:在中文中穿插数学符号或公式、穿插类似于说明书内容有时会用到的小图标等等。当我们认定写作的主环境是中文,便应把中文的主环境的书写习惯运用在每一个亚环境(英文、数学符号或公式、小图标等嵌入)以外的地方。

比如对于「有一個Windows Update可用」这句话,「有一个……可用」是中文的主环境,而「Windows Update」是中文主环境里面的英文亚环境。中文的书写里没有半角空格,英文亚环境也应只包含「Windows Update」而不应在其左右两边各加一个空格。如此看,也解决了bink Sponge认为「有一個Windows Update可用」被空格分成了「有一個Windows」和「Update可用」两部分的问题——因为中间的空格在语义上不是中文主环境的成分,也自然不会在语义上把整个中文主环境切割开。一个类似的例子是:就像两个段落之间插入的图片恰好有水平连续几行的空白像素,这种情况不存在结构性的问题——它不会从结构上让把内容分成「段落1与上半张图」和「下半张图与段落2」。

我十分认同bink Sponge提到的「尊重每種語言文字的书写习惯」的重要性,但正因如此,我才更坚定地认为半角空格不在中文书写习惯之内,不宜用在中文为主环境的文本中。

可能更好的解决方案

中西文之间空白的解决方案不是大家迫切会讨论的话题。但这么多年过去了也已经见到了不少方案,其中包括诸如自动给中西文之间插入半角空格的插件例如pangu.js。然而如果以上面的讨论为基础,相信中文为主环境的本文内中西文之间的空白不应由写作者处理而应交给排版引擎的话,我更有兴趣了解不添加空格的解决方案。下面便列举这些,其中也分享一个我自己开发的方案。

Microsoft IE 8的auto-space-property

auto-space-property是微软在Windows Internet Explorer 8的标准下的一个CSS样式。它有五种可能的值可以不同程度地调节「表意文字(Ideograph)」与其它文字之间的间距。

我没有想到对这一细节作出考虑的是微软,而且是在一个相对那么早的时候提出。但不知是不是因为这个CSS属性考虑不够周全,一直到目前都仅IE一家浏览器对它有支持,令人惋惜。

iOS 13 beta的1/8em

2019年六月发布的iOS 13 beta在中西文之间的空白上下了一定功夫。在iOS 13 beta中,第一次从系统层面上任何中英文之间的字距被调整为约1/8em左右。而后在iOS 13 beta 4中即使在中英文间手动插入半角空格也会被显示成1/8em大小而非常规空格,使肉眼无法分辨这里是否存在半角空格——这一做法一部分人(如李如一)认为使「两难消失」,另一部分人(如bink SpongeTualatriX)认为「不妙」或「粗暴」。iOS 13 beta 5又取消了手动插入的半角空格的大小变化。

我认为iOS做了一个很好的尝试。虽说我也认同beta 4中使肉眼无法区分空格是否存在的做法是粗暴的,原因不仅是肉眼是否可见的问题,还包括像上面所说的在空格存在语义时(例如由西文为主环境中文为亚环境)的行文中这种配置并不合理。好在beta 5取消了这一变化。总体而言,iOS正确从系统层面处理了中西文混排的空白问题。

Zige.js

Zige.js(字格)是我自己花一天编写的一个JavaScript代码,使开发者可以在原网页里添加仅一行代码来改善网页上中西文之间的字距1

在最近COVID-19疫情期间,某一天我开始学习日语时突然想到关于中西文混排的这个关注多时的问题。于是从知乎回答里看到知乎用户千鸟2011年提到的使用HTML span和CSS margin的方法增加网页上中西文之间的字距,这个方法从技术上很说得通因为span tag适用的功能恰是文本主环境中的亚环境。我不曾发现有人实现过,于是花一天时间实现了出来,测试发现效果不错,于是把它开源。

spanmargin一定不是这个问题最终的解法,因为最终排版的问题应当交给字体和系统的排版引擎。但根据前文所述,我相信这会是比添加空格(不管手动还是自动)更好的办法。我希望这个项目最终会不再被需要,因为它期待的是一个成熟的中文排版引擎的早日诞生。

在编写Zige.js后,我给知乎钱争予千鸟发去私信寻求意见,才了解到几乎做着相同事情但做得更全面的Han.css的存在。

Han.css

Han.css(漢字標準格式)是一个集「语意样式标准化」「文字设计」「高阶排版功能」三大概念的Sass/Stylus、JavaScript排版框架。它能实现的不仅是中西文字距,还包括装饰线着重号样式、多种汉字字体、和排版上的章节边界调整甚至标点挤压等。

同样,这个不会是解决问题的终极方案。但在这个排版引擎技术仍然受限的今天,我对这样的项目真的存在感到十分兴奋和敬佩。

成熟的排版引擎

说了许多空格在中文主环境的中西混排里为何是不合理的。但如我开头所说,我也仍在排版处理不当的软件里保留着为了样式而手动按空格键的习惯,就像程序员在没有文字自动换行的环境里甚至按回车键来换行一样。中西文间空白的问题不是单独的问题,与之相伴的还有CJK文字和各语言文字的混排、各标点在一起时应有的标点挤压,以及更多。每敲击一次不应属于它的按键,都是我对一个在更成熟的排版引擎的期待。

  1. 本站中文网页均已使用Zige.js来改善字距。