中文排版与国际化设计规范
AI 导读
中文排版与国际化设计规范 CJK 排版、竖排文字与多语言界面设计 1. 中文排版的独特性 中文排版与西文排版有本质差异。西文是"词"为基本单位,用空格分隔,字母等宽或变宽混合;中文是"字"为基本单位,无空格分隔,每个字符占据一个正方形的"字身"。这些差异深刻影响了换行、对齐、间距和字体选择。 西文排版: The quick brown fox jumps. | | | | | | [词] [词]...
中文排版与国际化设计规范
CJK 排版、竖排文字与多语言界面设计
1. 中文排版的独特性
中文排版与西文排版有本质差异。西文是"词"为基本单位,用空格分隔,字母等宽或变宽混合;中文是"字"为基本单位,无空格分隔,每个字符占据一个正方形的"字身"。这些差异深刻影响了换行、对齐、间距和字体选择。
西文排版:
The quick brown fox jumps.
| | | | | |
[词] [词] [词] [词] [词] <- 以词为单位,空格分隔
中文排版:
这是一段中文排版示例文字。
| | | | | | | | | | | | |
[字][字][字]...[字][字][字] <- 以字为单位,无分隔
1.1 关键术语
| 术语 | 定义 | 设计影响 |
|---|---|---|
| 字身 | 每个字符占据的虚拟方块 | 字号 = 字身宽度 = 字身高度 |
| 避头尾 | 特定标点不出现在行首/行尾 | 需要换行算法支持 |
| 全角/半角 | 全角占一个字身,半角占半个 | 中英混排时需处理 |
| 直排/横排 | 文字方向:纵向/横向 | CSS writing-mode |
| 标点悬挂 | 行尾标点可悬挂在版心外 | hanging-punctuation |
2. 字体选择
2.1 中文字体分类
| 类别 | 特征 | 适用场景 | 代表字体 |
|---|---|---|---|
| 黑体 | 笔画粗细均匀,无衬线 | 标题、UI 界面 | 思源黑体、苹方 |
| 宋体 | 横细竖粗,有衬线 | 正文、印刷 | 思源宋体、方正书宋 |
| 楷体 | 模仿手写,笔画有起收 | 引用、文学 | 楷体、方正楷体 |
| 圆体 | 笔画末端圆润 | 儿童、轻松场景 | 苹方-简 粗、圆体 |
| 等宽 | 所有字符等宽 | 代码显示 | Sarasa Mono SC |
2.2 中文 Web 字体策略
/* 推荐的中文字体栈 */
/* 方案 A: 系统字体优先(加载快,体验一致) */
.font-system-zh {
font-family:
-apple-system, /* macOS/iOS 苹方 */
"PingFang SC", /* macOS 苹方(显式声明) */
"Microsoft YaHei", /* Windows 微软雅黑 */
"Noto Sans SC", /* Android/Linux */
"Source Han Sans SC", /* 跨平台开源 */
sans-serif;
}
/* 方案 B: Web Font(品牌一致性,加载较慢) */
@font-face {
font-family: "Source Han Sans SC";
src: url("/fonts/SourceHanSansSC-Regular.woff2") format("woff2");
font-weight: 400;
font-display: swap; /* 先显示后替换,避免 FOIT */
unicode-range: U+4E00-9FFF, U+3400-4DBF; /* 只加载中文字符 */
}
/* 方案 C: 子集化(仅加载页面用到的字符) */
/* 使用 fonttools 的 pyftsubset 工具 */
/* pyftsubset font.otf --text-file=chars.txt --output-file=subset.woff2 */
2.3 字体文件大小
| 字体 | 全量 | 常用 6000 字子集 | 格式 |
|---|---|---|---|
| 思源黑体 Regular | 8.5 MB | ~1.2 MB | OTF |
| 思源黑体 Regular | 4.2 MB | ~600 KB | WOFF2 |
| Noto Sans SC Regular | 8.8 MB | ~1.3 MB | OTF |
| Noto Sans SC Regular | 4.5 MB | ~650 KB | WOFF2 |
3. 中文排版 CSS 规范
3.1 基础排版
/* 中文正文排版基础 */
.zh-body {
/* 字体 */
font-family: "Source Han Sans SC", "PingFang SC", sans-serif;
font-size: 16px;
font-weight: 400;
/* 行高: 中文推荐 1.6-1.8 倍(高于西文的 1.4-1.5) */
line-height: 1.75;
/* 段落间距 */
margin-bottom: 1em;
/* 对齐: 两端对齐 */
text-align: justify;
text-justify: inter-ideograph; /* CJK 字间调整 */
/* 换行控制 */
word-break: normal;
overflow-wrap: break-word;
line-break: strict; /* 严格避头尾规则 */
/* 字间距: 中文一般不需要额外字间距 */
letter-spacing: 0;
/* 标点处理 */
hanging-punctuation: allow-end; /* 行尾标点悬挂 */
/* 颜色: 中文正文推荐深灰而非纯黑 */
color: #333333;
}
/* 标题 */
.zh-heading {
font-weight: 700; /* 中文加粗需要 700 */
line-height: 1.3; /* 标题行高较紧 */
letter-spacing: 0.02em; /* 标题可微调字间距 */
}
3.2 避头尾规则
不可出现在行首的字符(避头):
,。、;:!?)》」』】〉》)
不可出现在行尾的字符(避尾):
(《「『【〈《(
/* CSS 原生避头尾 */
.zh-text {
line-break: strict;
/* strict 模式下,浏览器自动处理 CJK 避头尾 */
}
3.3 中英文混排
/* 中英文混排间距 */
.zh-mixed {
/* 方案 A: CSS text-autospace (新标准,浏览器支持有限) */
text-autospace: ideograph-alpha ideograph-numeric;
/* 方案 B: 手动处理 */
/* 使用 JavaScript 在中文与英文之间插入 thin space */
}
// JavaScript 自动插入中英文间距
function addCJKSpacing(text) {
return text
// 中文后跟英文/数字
.replace(/([\u4e00-\u9fff])([\w])/g, '$1\u2006$2')
// 英文/数字后跟中文
.replace(/([\w])([\u4e00-\u9fff])/g, '$1\u2006$2');
// \u2006 = Six-Per-Em Space (1/6 em)
}
4. 竖排文字
4.1 CSS 竖排
/* 竖排排版 */
.vertical-text {
writing-mode: vertical-rl; /* 从右到左竖排 */
text-orientation: mixed; /* 中文竖排,英文横转 */
/* 或 */
writing-mode: vertical-lr; /* 从左到右竖排(蒙古文等) */
}
/* 竖排中的数字处理 */
.vertical-text .number {
text-combine-upright: all; /* 两位数字横排 */
/* 或 */
text-orientation: upright; /* 数字也竖排 */
}
4.2 竖排常见问题
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 标点位置错误 | 标点未随文字旋转 | font-feature-settings: "vrt2" |
| 英文方向错误 | 默认旋转90度 | text-orientation: mixed |
| 行距不均 | 全角半角混排 | 统一使用全角标点 |
| 连续数字 | 3-4位数字挤在一竖 | text-combine-upright: digits 2 |
| 表情符号 | 可能被旋转 | unicode-bidi: plaintext |
5. 国际化(i18n)设计
5.1 多语言界面挑战
| 挑战 | 中文 | 英文 | 阿拉伯文 | 日文 |
|---|---|---|---|---|
| 文字方向 | LTR | LTR | RTL | LTR/竖排 |
| 文字长度 | 短(表意文字) | 中 | 中 | 短-中 |
| 换行规则 | 按字换行 | 按词换行 | 按词换行 | 复合规则 |
| 字体体积 | 大(数万字) | 小(百字母) | 小 | 大 |
| 复数形式 | 无 | 2 种 | 6 种 | 无 |
| 数字格式 | 1,234.56 | 1,234.56 | 1,234.56 | 1,234.56 |
| 日期格式 | 2026年2月28日 | Feb 28, 2026 | 28/02/2026 | 2026/02/28 |
5.2 文本扩展预算
翻译后文本长度变化参考(以英文为基准):
| 目标语言 | 扩展比例 | 示例 |
|---|---|---|
| 中文 | 0.6-0.8x | "Save" -> "保存" |
| 日文 | 0.8-1.2x | "Save" -> "保存する" |
| 德文 | 1.3-1.8x | "Save" -> "Speichern" |
| 法文 | 1.2-1.6x | "Save" -> "Sauvegarder" |
| 阿拉伯文 | 1.2-1.5x | 从右到左 |
| 俄文 | 1.3-1.7x | "Save" -> "Сохранить" |
设计中必须为文本预留 50% 的扩展空间。
5.3 Flex 布局应对文本扩展
/* 不要固定宽度 */
.button {
/* 错误: width: 80px; */
/* 正确: */
min-width: 80px;
padding: 8px 16px;
white-space: nowrap;
}
/* 使用 flex 自适应 */
.nav-bar {
display: flex;
flex-wrap: wrap; /* 允许换行,避免溢出 */
gap: 8px;
}
.nav-item {
flex-shrink: 0; /* 不压缩 */
}
5.4 RTL(从右到左)支持
/* 逻辑属性替代物理属性 */
.card {
/* 物理属性 (不推荐): */
/* margin-left: 16px; */
/* padding-right: 24px; */
/* text-align: left; */
/* 逻辑属性 (推荐): */
margin-inline-start: 16px;
padding-inline-end: 24px;
text-align: start;
}
/* 图标翻转 */
[dir="rtl"] .icon-arrow-right {
transform: scaleX(-1); /* 水平翻转箭头 */
}
/* 但是! 某些图标不应翻转 */
[dir="rtl"] .icon-clock,
[dir="rtl"] .icon-phone,
[dir="rtl"] .icon-search {
transform: none; /* 时钟、电话、搜索不翻转 */
}
6. 数字与日期格式化
6.1 Intl API
// 数字格式化
function formatNumber(value, locale) {
return new Intl.NumberFormat(locale).format(value);
}
formatNumber(1234567.89, 'zh-CN'); // "1,234,567.89"
formatNumber(1234567.89, 'de-DE'); // "1.234.567,89"
formatNumber(1234567.89, 'ja-JP'); // "1,234,567.89"
// 货币格式化
function formatCurrency(value, locale, currency) {
return new Intl.NumberFormat(locale, {
style: 'currency',
currency: currency
}).format(value);
}
formatCurrency(1234.5, 'zh-CN', 'CNY'); // "CN\u00a51,234.50"
formatCurrency(1234.5, 'en-US', 'USD'); // "$1,234.50"
formatCurrency(1234.5, 'ja-JP', 'JPY'); // "JP\u00a51,235"
// 日期格式化
function formatDate(date, locale) {
return new Intl.DateTimeFormat(locale, {
year: 'numeric',
month: 'long',
day: 'numeric'
}).format(date);
}
formatDate(new Date(), 'zh-CN'); // "2026年2月28日"
formatDate(new Date(), 'en-US'); // "February 28, 2026"
formatDate(new Date(), 'ja-JP'); // "2026年2月28日"
// 相对时间
function formatRelative(date, locale) {
const rtf = new Intl.RelativeTimeFormat(locale, { numeric: 'auto' });
const diff = Math.round((date - Date.now()) / (1000 * 60 * 60 * 24));
return rtf.format(diff, 'day');
}
formatRelative(yesterday, 'zh-CN'); // "昨天"
formatRelative(yesterday, 'en-US'); // "yesterday"
7. 排版质量检查
7.1 自动化检查清单
| 检查项 | 规则 | 工具 |
|---|---|---|
| 字体回退 | 中文字体不可用时有合理回退 | Playwright 截图对比 |
| 行首标点 | 无避头标点出现在行首 | 正则扫描 + 视觉检查 |
| 中英间距 | 中英文之间有适当间距 | 自动检测脚本 |
| 行长 | 中文每行 25-40 字 | CSS 检查 max-width |
| 行高 | 中文正文行高 >= 1.6 | CSS 检查 line-height |
| 字号 | 正文 >= 14px | CSS 检查 font-size |
| 文本扩展 | 界面元素容纳 1.5x 文本 | 伪翻译测试 |
| RTL 布局 | 逻辑属性替代物理属性 | stylelint 规则 |
7.2 伪翻译测试
// 伪翻译: 用扩展字符替换,测试布局弹性
function pseudoTranslate(text, expansionFactor = 1.5) {
const expanded = text
.split('')
.map(char => {
if (/[a-zA-Z]/.test(char)) {
// 用带音调的字符替换,增加视觉标识
const map = { a: 'a', e: 'e', i: 'i', o: 'o', u: 'u' };
return (map[char.toLowerCase()] || char).repeat(
Math.ceil(expansionFactor)
);
}
return char;
})
.join('');
return `[${expanded}]`; // 方括号标识伪翻译
}
// "Save" -> "[Saavee]"
// "Cancel" -> "[Caannceell]"
8. CJK 特殊场景处理
8.1 表格中的中文
.zh-table {
/* 中文表格不要 nowrap,允许单元格内换行 */
word-break: break-all; /* CJK 允许任意位置换行 */
/* 数字列右对齐 */
td.number { text-align: right; font-variant-numeric: tabular-nums; }
/* 中文列左对齐 */
td.text { text-align: start; }
}
8.2 输入法兼容
// 中文输入法组合事件处理
let isComposing = false;
input.addEventListener('compositionstart', () => {
isComposing = true;
});
input.addEventListener('compositionend', (e) => {
isComposing = false;
// 在这里处理最终输入,而不是在 input 事件中
handleInput(e.target.value);
});
input.addEventListener('input', (e) => {
if (isComposing) return; // 组合输入中,不触发搜索/验证
handleInput(e.target.value);
});
8.3 文本截断
/* 中文单行截断 */
.zh-truncate {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
/* 中文多行截断 */
.zh-line-clamp {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3; /* 最多 3 行 */
overflow: hidden;
}
9. 性能优化
9.1 字体加载策略
策略对比:
+------------------+--------+----------+
| 策略 | FOIT | FOUT |
+------------------+--------+----------+
| font-display:auto | 3s闪白 | 无 |
| font-display:swap | 无 | 字体闪跳 |
| font-display:optional | 无 | 无(可能不加载)|
| 预加载 + swap | 极短 | 极短 |
+------------------+--------+----------+
推荐方案: 预加载 + swap
<!-- 预加载中文字体 -->
<link
rel="preload"
href="/fonts/SourceHanSansSC-Regular-subset.woff2"
as="font"
type="font/woff2"
crossorigin
>
9.2 按需加载
// Google Fonts 按 unicode-range 分片加载
// 浏览器只下载页面中实际使用到的字符范围
@font-face {
font-family: 'Noto Sans SC';
src: url('NotoSansSC-Regular.1.woff2') format('woff2');
unicode-range: U+fee3, U+fef3, U+ff03-ff04, U+ff07, U+ff0a-ff0b;
}
@font-face {
font-family: 'Noto Sans SC';
src: url('NotoSansSC-Regular.2.woff2') format('woff2');
unicode-range: U+5408, U+5409, U+540a-540d, U+540f-5411, U+5413;
}
/* ... 数十个分片 */
10. 工具与参考
| 工具 | 用途 |
|---|---|
| pyftsubset (fonttools) | 字体子集化 |
| cn-font-split | 中文字体自动分包 |
| Google Fonts | 中文 Web 字体 CDN |
| text-autospace polyfill | 中英间距自动处理 |
| stylelint-i18n | i18n CSS 规则检查 |
| ICU MessageFormat | 国际化消息格式 |
| Intl API | 浏览器原生国际化 |
| i18next | 前端 i18n 框架 |
参考规范:
| 规范 | 说明 |
|---|---|
| W3C CLReq | 中文排版需求 (Requirements for Chinese Text Layout) |
| W3C JLReq | 日文排版需求 |
| Unicode UAX #14 | Unicode 换行算法 |
| Unicode UAX #11 | 东亚字符宽度 |
| CSS Writing Modes L4 | 竖排排版规范 |
| CSS Text L4 | 文本处理规范 |
Maurice | [email protected]
深度加工(NotebookLM 生成)
基于本文内容生成的 PPT 大纲、博客摘要、短视频脚本与 Deep Dive 播客,用于多场景复用
PPT 大纲(5-8 张幻灯片) 点击展开
中文排版与国际化设计规范 — ppt
以下是基于您上传的文章为您整理的 6 张幻灯片 PPT 大纲,采用 Markdown 格式输出:
中文排版独特性与核心术语
- 中西文排版本质差异:西文以“词”为基本单位并用空格分隔,而中文以“字”为单位,无空格分隔且每个字符占据一个正方形的“字身” [1]。
- 核心排版概念:掌握字身(决定字号大小)、全角/半角(中英混排占用空间比例)等基础设计概念 [1]。
- 严格的避头尾规则:特定标点(如逗号、句号、右括号)不可出现在行首,前括号等不可出现在行尾,需依赖专门的换行算法 [1]。
- 标点悬挂处理:为了保持版心边界的视觉整洁,行尾标点可以悬挂在版心之外 [1]。
中文字体选择与前端加载策略
- 常见中文字体与场景:涵盖黑体(适合标题与 UI 界面)、宋体(适合正文与印刷)、楷体(适合引用)及等宽字体(适合代码显示) [1]。
- Web 字体三大策略:包括“系统字体优先”(加载最快)、“Web Font”(保证品牌一致性但加载较慢)以及“子集化”(仅加载所需字符以减小体积) [1]。
- 字体体积与加载优化:全量中文字体可达 4-8 MB,通过提取常用 6000 字子集可缩减至约 600 KB [1]。推荐结合“预加载 +
font-display: swap”与unicode-range进行按需分片加载 [1, 2]。
中文 Web 基础排版规范
- 正文与标题参数:中文正文推荐较宽的 1.6-1.8 倍行高(高于西文),且中文字体加粗需设置
font-weight: 700[1]。 - 对齐与换行模式:推荐使用
text-align: justify实现两端对齐,并开启line-break: strict让浏览器自动处理严格避头尾 [1]。 - 中英文字符混排处理:中文与英文/数字间需保持适当间距,可通过较新的 CSS
text-autospace标准实现,或借助 JavaScript 手动插入较窄的空格(如 1/6 em) [1, 3]。 - 长文本截断方案:支持通过 CSS 轻松实现中文单行截断(
white-space: nowrap)及多行截断(使用-webkit-line-clamp) [2]。
竖排文字设计与特殊场景处理
- 竖排 CSS 原生实现:利用
writing-mode: vertical-rl轻松完成从右到左的中文竖排,并使用text-orientation: mixed让英文自然横转 [3]。 - 竖排中的数字与标点:解决标点位置错误需配置
font-feature-settings: "vrt2",且通过text-combine-upright确保连续多位数字不会过度拥挤 [3]。 - CJK 表格排版规范:中文表格不建议禁止换行,应允许单元格内任意换行(
word-break: break-all),并将数字列统一右对齐 [2]。 - 输入法(IME)兼容机制:在监听用户输入时,需结合
compositionstart和compositionend事件,避免输入法正在拼写组合时误触发搜索或验证 [2]。
多语言(i18n)界面设计与弹性布局
- 全球化多语言特性差异:不同语言面临着不同的文字方向(如阿拉伯文的 RTL)、换行规则(按词或按字)以及数字/日期格式化挑战 [3]。
- 文本扩展空间预算预留:以英文为基准,翻译为其他语言(如德语、俄语)时长度通常会膨胀 1.3-1.8 倍,设计时必须预留约 50% 的宽裕空间 [3]。
- 响应式自适应布局:严禁使用固定宽度限制文本,推荐使用
min-width与 Flexbox 换行机制(flex-wrap: wrap)防止内容溢出 [3]。 - RTL(从右到左)布局适配:推广使用逻辑属性(如
margin-inline-start)替代物理属性,并有选择地水平翻转箭头等具有方向性的图标 [3]。
国际化数据格式化与排版质量检测
- 原生 Intl API 格式化:全量拥抱浏览器原生的
IntlAPI,快速对数字、货币符号、日期甚至是“昨天”等相对时间进行多语言标准化处理 [2, 3]。 - 自动化排版质量巡检:建立完整的自动化检查清单,通过相关工具检测字体回退机制、行头标点、中英间距、行长以及行高是否符合规范 [2]。
- 伪翻译测试机制(Pseudo-translation):在开发阶段使用带音调扩展字符(如将 "Save" 替换为 "[Saavee]")来模拟外语长度,以提前检验前端布局的容错率与弹性 [2]。
博客摘要 + 核心看点 点击展开
中文排版与国际化设计规范 — summary
SEO 博客摘要
本文深入解析中文排版与国际化(i18n)设计规范,为前端开发者提供系统性指南。内容涵盖中文字体加载策略、CSS排版技巧、中英混排与严格避头尾规则 [1]。同时,针对多语言界面设计,详细讲解了文本扩展的弹性布局应对、RTL(从右到左)布局支持、Intl API 格式化应用,以及大体积中文字体的性能优化(如字库子集化与预加载策略),助力打造体验一致的高质量全球化 Web 应用 [2, 3]。
核心看点
- 中文专属排版方案:详解 CSS 严格避头尾、行尾标点悬挂及中英混排间距处理 [1]。
- 多语言界面适配:应对文本扩展挑战,灵活运用 Flex 弹性布局与 RTL 逻辑属性 [2]。
- Web字体性能优化:解析字体子集化、分片下载与按需加载策略,拒绝加载闪烁 [1, 3]。
60 秒短视频脚本 点击展开
中文排版与国际化设计规范 — video
这是一份基于您提供的《中文排版与国际化设计规范》提炼的 60 秒短视频脚本。严格按照您的字数和结构要求编写:
【钩子开场】(12字)
中文网页排版,你做对了吗?
【核心解说 1:基础差异】(27字)
中文以字为单位,无空格分隔 [1]。排版时行高推荐设为1.6到1.8倍,阅读更佳 [1]。
【核心解说 2:排版细节】(29字)
严守避头尾规则,标点不占行首 [1]。中英文混排需加微小间距,视觉才更精致 [1, 2]。
【核心解说 3:国际化适配】(29字)
多语言界面翻译后会变长,必须预留50%的扩展空间,并多用弹性布局 [2]。
【一句收束】
掌握这些排版细节,让你的界面更显专业!
课后巩固
与本文内容匹配的闪卡与测验,帮助巩固所学知识
延伸阅读
根据本文主题,为你推荐相关的学习资料