3144 字
约 10 分钟
17
S10-A10 · 多语言内容的工程化:不是翻译就能上线

翻译做完了,术语表也过了,上线当天日文版把按钮撑破,德语版把一行标题挤成三行,阿拉伯语版整个布局从右往左错位。翻译质量没问题,出问题的是排版与语义——这两块在翻译阶段根本没人看。

多语言的成本从来不是一项,而是三项,且它们在不同的阶段暴露。把三项分开预算,很多"上线才发现"的问题会提前变成"设计时就知道"。


1. 三种成本与各自的发现阶段

成本 内容 通常在哪暴露 事后修复代价
翻译成本 人力、术语一致性、审校轮次 翻译阶段,可见 中,可增量补
排版成本 文案长度变化、断行、容器尺寸 上线后,肉眼可见 高,牵动布局与设计
语义成本 复数、性别、语序、占位符、语气 上线后,通常只有母语用户发现 最高,牵动文案结构

常见误判是把预算全压在翻译上。翻译错一句可以改一句;语义错会让整类文案都要重写,因为键的结构本身不支持那种语言。

2. 哪些内容该翻译、哪些不该

内容类型 策略 判据
界面文案、错误提示 翻译 用户直接阅读,影响任务完成
技术术语(API、token、commit) 保留原文,必要时加简短注释 译名反而制造检索障碍
品牌名与产品代号 不翻译 翻译会破坏可识别性
法律条款、隐私政策 通常只保证一种语言为权威文本 多语言并存会产生解释冲突
日志与堆栈 不翻译 面向排查者,需与代码一致
帮助文档 按版本翻译,不全量 版本更新快,翻译会长期落后

"全部都翻"听上去最尊重用户,实际结果是术语混乱 + 维护面积翻倍。

3. 扩缩率与布局预留

同一句话在不同语言下的长度差异是结构性的,不是翻译不精炼。做布局时按最坏情况预留:

源语言 → 目标 典型长度变化 布局影响
en → de 明显变长,常见 1.3 倍量级 按钮、标签、表头溢出
en → ja / zh 明显变短 留白过大,对齐错位
en → ru / fi 变长且词形长 输入框、面包屑截断
// 预留策略:容器按最长目标语言设计,而不是按源语言
.btn { min-width: 9rem; padding-inline: 1rem; }   // 不用固定 width
.label { white-space: normal; overflow-wrap: anywhere; }  // 允许两行
.table th { min-width: 6rem; }                     // 表头按最坏语种

固定像素宽 + nowrap 是排版事故的第一组合;min-width + 允许换行是成本最低的防线。

4. 复数、性别、语序与占位符

占位符拼接是最容易在翻译里"合法地写错"的地方:

// 反例:拼接式,语序被写死在代码里
"items": "You have " + N + " new items"
// 正例:整句交给消息格式,语序由译者决定
"items": "{count, plural, =0 {No new items} one {# new item} other {# new items}}"
坑 表现 处理
复数规则 英、日只有两形,俄、阿有多形 用 ICU 复数类别,不写 if (n > 1)
性别 部分语言形容词随性别变化 消息里带 gender 参数,或改写为中性句
语序 动词、宾语位置不同 整句做键,不做片段拼接
占位符顺序 译者调整顺序后参数错位 具名占位符,禁止位置参数
标点与空格 句末标点、全角半角不同 标点进消息体,不入代码

5. 日期、数字、货币与姓名

本地化不只影响显示,还影响存储:存显示值是最常见的不可逆错误。

数据 存储形态 渲染时机
时间 时间戳或 UTC 按用户 locale 与时区渲染
数字 数值类型 按 locale 分组与小数位渲染
货币 金额 + 币种代码 渲染时决定符号与位置
姓名 单字段或分字段,按业务定 不假设"名在前"
地址 分字段 + 国家 不假设省市区层级固定
// 反例:存渲染后的字符串,等于把语言绑进数据
INSERT INTO orders (amount_text) VALUES ('¥1,299.00');
// 正例:存金额与币种,渲染交给展示层
INSERT INTO orders (amount, currency) VALUES (1299.00, 'CNY');
// 渲染侧按请求 locale 输出,不做全局默认
String s = NumberFormat.getCurrencyInstance(locale).format(amount);

6. "语言"与"地区"是两个变量

组合 差异点 只按语言处理会怎样
zh-CN / zh-TW 用词与字形不同 用简体文案覆盖繁体用户
pt-BR / pt-PT 词汇与语序不同 一方读起来别扭但能懂
en-US / en-GB 日期顺序、拼写 日期被读错(03/04)
es-ES / es-MX 称谓与货币 货币符号错,金额被误解

键的设计要按 language-REGION 定位,但回退链按 language 走:缺 pt-PT 时回退到 pt 再回退到默认语言,而不是直接跳到英文。

7. 源文案改了,怎么传导

更新机制的核心不是翻译工具,而是变更可追:

// 源文案变更 → 标出受影响的目标语言键
extract-strings --src src/ --out locale/en.json
diff -u locale/en.prev.json locale/en.json | grep '^[+-]' \
  | grep -v '^[+-][+-]' > changed.txt      // 只留变更键
for f in locale/*.json; do
  missing=$(comm -23 <(sort changed.txt) <(sort "$f")); echo "$f $missing"
done
机制 传导时延 适合场景
键级 diff + 待翻译队列 分钟到小时 常规迭代
全量重翻 天 大版本重构
按页面整块重翻 中 文案成块改写的产品
不传导,靠人发现 无上限 不应存在

8. 回退策略:缺翻译时显示什么

// 回退链:语言 → 同语言其他地区 → 默认语言 → 占位提示
{ "fallback": ["ja-JP", "ja", "en"], "onMissing": "LOUD_PLACEHOLDER" }
策略 用户体验 风险
回退到默认语言 可读,但语言混杂 用户以为漏翻
显示源 key(如 btn.submit) 明显异常 把内部标识暴露给用户
显示占位符([ja] 提交) 可读且可识别 需前端支持
隐藏该条目 干净 功能入口消失,用户找不到

底线只有一条:绝不能把 key 直接显示给用户。其余三种按产品取舍。

9. 机器翻译的可用边界

场景 可用性 原因
短 UI 标签、按钮 可用,需抽检 上下文少,歧义小
错误提示 谨慎 一句错译会让用户做错动作
长文档、帮助中心 不可直接上线 术语与语气漂移,需术语表约束
法律与合规文本 不可 解释权与责任问题
术语表覆盖的词 强约束下可用 必须强制替换,不允许模型自选译名

机器翻译的正确位置是草稿与冷启动,不是终稿;术语表必须作为硬约束而不是提示词建议。

10. 验收判据:能不能完成任务,而不是像不像母语

判据 通过标准 反例
任务可完成 母语用户不看原文能完成操作 文案优美但按钮含义含糊
术语一致 同一概念全文一个译名 三处三种叫法
无截断溢出 最长语言下无遮挡、无省略号 按钮文字被裁
占位符正确 变量值出现在正确位置 金额与币种错位
无残留 无未翻译条目、无 key 外露 页面夹带英文片段

"读起来像母语"是加分项,不是验收项;验收项是用户能否完成任务。

11. RTL 的额外成本

维度 LTR 做法 RTL 需要额外处理
布局方向 margin-left 逻辑属性 margin-inline-start
图标方向 箭头朝右 图标需镜像,非全部可镜像
数字与代码 随文本流 需显式 LTR 隔离,否则被翻转
滚动与对齐 左对齐 起点在右,进度条方向反转
设计稿 一套 通常需要一套镜像稿或严格逻辑属性
// 用逻辑属性替换方向属性,一套 CSS 覆盖两侧
.panel { margin-inline-start: 1rem; text-align: start; direction: inherit; }
.code  { direction: ltr; unicode-bidi: isolate; }  // 代码块不参与翻转

RTL 的成本主要在设计资产与图标,不在 CSS 本身。

12. 度量

指标 口径 异常信号
翻译覆盖率 已译键 / 源键 某语言长期低于其余语言
过期翻译数 源键变更后未更新 单调上升
布局溢出数 视觉回归中溢出的容器数 新增语言上线后突增
传导时延 源变更到目标语言上线 超过一个迭代
回退命中率 回退到默认语言的请求占比 高且不降,说明翻译长期缺位

13. 排错:五种"翻完了还是不能用"

现象 原因 处理
按钮文字被裁 固定宽度 + 不换行 改 min-width,允许两行
某语言永远显示英文 回退链跳过该语言 检查 locale 解析与键前缀
金额显示成另一种货币 存了渲染值或默认 locale 写死 存金额 + 币种,渲染按请求 locale
复数句子总是"1 items" 用 if 判复数 改用 ICU 复数类别
阿拉伯语页面整体错位 用物理方向属性 换逻辑属性,图标单独镜像

14. 边界:什么情况完整 i18n 框架是过度设计

情形 合理做法 理由
单语言产品 只做字符串外置 无翻译需求,但外置为后续留口
内部工具 字符串外置 + 默认语言 读者同语种,翻译无收益
用户集中在一个地区 区域格式按该地区固定 多 locale 分支是无效复杂度
内容一周内迭代多次 先稳文案,再谈翻译 译完即过期
只有一种权威法律文本 其余语言标注"仅供参考" 避免解释冲突

但字符串外置这一层几乎总是值得做:它把"改一句话"从改代码变成改数据,成本极低,且是后续任何多语言方案的前置条件。


15. 自测

  1. 三种多语言成本里,哪一项最容易在上线首日暴露?
  2. 为什么技术术语通常保留原文而不翻译?
  3. 按钮宽度该按源语言还是最长目标语言设计?
  4. 复数处理为什么不能写成 if (n > 1)?
  5. 缺翻译时唯一不能采取的回退方式是什么?
  6. 单语言产品为什么仍值得做字符串外置?
S10-A10 · 多语言内容的工程化:不是翻译就能上线
https://www.clxhxhhr.top/posts/6293/
作者
clxstart
发布于
2024-12-31
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。