排版设计

中文网页排版里,那些一眼看不出但一直在起作用的细节

汉字与拉丁字母的相处方式,决定了一段中文读起来是舒服还是别扭

目录

一段中文读起来舒不舒服,通常不取决于用了什么字体。字体是最容易被讨论、也最容易被高估的一环。真正在起作用的,是一批读者永远不会主动注意、但只要做错就会持续制造摩擦的细节。

它们的共同点是:做对了没人夸,做错了没人说得上来哪里不对,只会觉得“这个网站看着有点累”。

中西文之间的那道缝#

汉字是方块字,字面几乎撑满字身框;拉丁字母是比例字,两侧天然带留白。这两种字挨在一起时,视觉上会挤成一团。

传统排版对此有明确规定:中西文之间加约四分之一个汉字宽的空隙这个空隙的学名很多:中西文混排间距、盘古之白、hanzi-western spacing。宽度在四分之一到八分之一汉字宽之间取值,取决于正文字号和字体的字面率。。这条规则在纸质书里执行了几十年,到了网页上却大面积失传,因为它需要在文本里插入一点东西,而大多数内容管理系统不提供这个能力。

常见的做法是直接插入空格字符。这解决了视觉问题,却制造了新问题:读者复制这段文字时,会带出一堆本不属于原文的空格。

更干净的做法

不插入字符,而是插入一个宽度为零、但左右带外边距的空元素。视觉上有间距,文本内容里却什么都没多出来。复制粘贴出去的是干净的原文。

这个站上你现在读到的每一处中西文交界,都由构建期的一遍扫描处理过。Claude CodeHugo 这样的词紧贴汉字时,缝隙是自动补上的——包括它们被包在链接或者行内代码里的时候,那种跨标签的接缝最容易漏掉。

标点不该总是占满一个字宽#

全角标点在字体里的设计宽度是一个完整汉字。这在竖排和格稿纸时代是对的,因为每个格子必须等宽。

但横排正文里,连续出现两个标点时,两个字宽的空白会在版面上撕开一个洞:

他问:“你确定吗?”——没有人回答。

这里的 "—— 连成一片,如果每个都占满字宽,这一行会明显比其他行松。专业排版的处理叫标点挤压:根据前后文压缩标点的实际占位。

现在的浏览器已经支持这件事,只需要一行样式:

正文的标点挤压CSS
body {
  text-spacing-trim: trim-start;
}

对应地,还有一条避头尾规则:句号、逗号、右引号不能出现在行首,左引号不能出现在行尾。CSS 的 line-break: strict 会处理大部分情况。

中文没有斜体#

这是被误用得最多的一条。

<em> 在浏览器里默认渲染成斜体。拉丁字母有专门设计的斜体字形,笔画结构会随之改变,不只是倾斜。汉字没有。浏览器遇到中文的 <em>,只能把正体字形做几何倾斜,结果是笔画粗细失衡、重心歪斜。

中文强调的传统形式是着重号——在字的下方(横排)或右侧(竖排)加点。国家标准里有明确规定GB/T 15834《标点符号用法》。着重号的位置在横排时位于字的下方。

问题在于,CSS 判断不了一个 <em> 里装的是汉字还是拉丁字母。所以这件事必须在生成页面的时候做:扫一遍文档结构,含中文的强调标一个记号,样式再据此分流。

内容 呈现方式 原因
中文强调 着重号 汉字没有斜体设计
西文强调 斜体 有专门设计的斜体字形
混排强调 着重号 以主体文字为准

行长与行距#

中文的合理行长比西文短。西文常用的经验值是每行 65 到 75 个字符,换算成汉字大约是 32 到 38 个字。超过这个范围,眼睛从行尾跳回下一行行首时容易串行。

行距则相反,中文需要得更多。汉字字面大、笔画密,字与字之间没有西文那样天然的疏密节奏,行距不足会让整段糊成一片。西文正文常用 1.5 到 1.6 倍,中文建议 1.75 到 1.9 倍。

这些细节值多少#

单独看,每一条都微不足道。四分之一个字宽的空隙、几个标点的挤压、强调用点还是用斜——任何一条都不足以让读者说出“这个页面排得好”。

但它们是叠加的。一页中文里有几百个中西文交界、几十处标点、若干处强调。全部做对和全部不做,读完一篇长文之后的疲劳程度是能感觉出来的——尽管读者说不清原因。

排版做到位的标志,从来不是被夸奖,而是被忘记。

esc