Monospace + letter-spacing 套中文:末尾汉字孤立换行的根因
做一个卡片列表页时,设计稿的元信息行(.vmeta)看起来挺工业感的——Space Mono 字体、letter-spacing: .14em、text-transform: uppercase,在英文内容下很好看。但当同一组样式套到中文属性串(比如「学校 · 年级 · 位置 · 特长」)上,在 375px 的手机屏里死活对不齐:最后两个汉字单独跑到第二行,页面上出现一个孤零零的「右脚」。
改了字号、改了容器宽度都没用,直到盯着 DevTools 里的 computed style 才意识到:letter-spacing 一直在偷偷加料。
现象
元信息行内容如下:
<div class="vmeta">余杭一小 · 五年级 · 前锋 · 右脚</div>对应样式:
.vmeta {
font-family: 'Space Mono', monospace;
font-size: 9px;
letter-spacing: .14em;
text-transform: uppercase;
}在 375px 视口下,缩去缩略图宽度和内边距后,.vmeta 容器只有约 201px,但这串 12 个汉字(含分隔点)实际渲染宽度约 210px——多了 9px,恰好把最后的「右脚」顶到第二行。
同一个 selector 复用了 16+ 张卡片,全部中招。
根因
W3C CSS Text 规范明确:letter-spacing 在每对相邻排版字符单元之间生效,CJK 表意字符不豁免。
计算一下:.14em 在 9px 字号下 = 0.14 × 9 = 1.26px/字符间隔。12 个汉字有 11 个字符间隔,额外宽度 = 11 × 1.26 ≈ 13.9px。这就是容器溢出的来源。
Webkit、Blink、Firefox、Safari 行为一致——这是规范定义的,不是浏览器 bug。
Space Mono + letter-spacing >= .1em + text-transform: uppercase 是英文「工业字体」三件套。在英文/数字行上完全正确,但直接套到中文元信息行时:
- 每个汉字都被加字距,12 个字就溢出 ~14px,末尾字符孤立换行
text-transform: uppercase对 CJK 无效,保留它既无用又干扰调试9px中文几乎不可读,但 Space Mono 英文在 9px 仍可读,所以问题被忽视
审 mockup 时,凡看见这三件套套在中文行上,几乎必有溢出。
正解
一处 CSS fix,覆盖所有复用点:
.vmeta {
/* 字体栈:中文走 PingFang SC,数字/英文 fallback 走 Space Mono
工业感被保留在它该出现的字符上,中文不受等宽字体影响 */
font-family: 'PingFang SC', 'Space Mono', monospace;
/* 字距大幅压低:.02em 保留一点间距感,但汉字不再膨胀 */
letter-spacing: .02em;
/* 字号提升:11px 是中文元信息舒适下限 */
font-size: 11px;
line-height: 1.45;
/* 删除 uppercase:对 CJK 无效,且让混排英文(如 U10)意外变形 */
/* text-transform: uppercase; */
color: var(--ink-mute);
}如果同一 selector 偶尔也要渲染纯英文/数字内容,加 modifier class 而不是全局改:
.vmeta.en {
font-family: 'Space Mono', monospace;
letter-spacing: .14em;
text-transform: uppercase;
font-size: 9px;
}配套数据精简(4 段属性仍偶尔溢出时):把次要属性从主元信息行移入下方 .tags chip 区,主行保留 3 段核心标识:
<!-- 改前:4 段挤在一行 -->
<div class="vmeta">余杭一小 · 五年级 · 前锋 · 右脚</div>
<!-- 改后:核心信息留主行,次要属性下沉 chip -->
<div class="vmeta">余杭一小 · 五年级 · 前锋</div>
<div class="tags">
<span>右脚</span>
<span>3 场</span>
<span>2 球</span>
</div>font-family: 'PingFang SC', 'Space Mono', monospace 是关键——浏览器按字符逐字选字体,中文走 PingFang SC,数字/英文 fallback 走 Space Mono,无需双 selector,工业感和可读性兼得。
验证
改完后三步确认:
- 截图对比改前/改后,同一卡片同一中文内容,确认末尾字符不再孤立换行
grep -n 'class="vmeta"'找出所有使用点,目测无 regression- 日期(
2026.03)、编号(U10)等数字/英文混排片段仍呈现等宽工业风,证明 fallback 字体链工作正常
一句话外卖
letter-spacing对 CJK 字符同样生效,英文设计稿直接拷贝到中文行时必须压字距、换字体栈,否则汉字数量一多必溢出。