必须用<rb>显式包裹基字,否则Firefox等浏览器不渲染拼音;多字需拆分为多个<ruby>,拼音须用Unicode声调、禁用全角符号,且需CSS设置font-size、line-height和white-space。

ruby 和 rt 标签必须配 才能稳定显示拼音
单独写 <ruby>汉<rt>hàn</rt></ruby> 在 Firefox 或新版 Edge 中根本不会渲染拼音——它会被当成普通文本,<rt> 内容直接平铺在汉字后面。这不是浏览器 bug,而是 HTML 规范明确要求:被注音的基字必须用 <rb> 显式包裹,<rt> 才能与其绑定。Chrome 和 Safari 虽然宽容,会自动把 <ruby> 里非 <rt> 的纯文本当作 <rb>,但靠这种“兼容性”上线,等于把渲染权交给浏览器猜。
正确结构只有一种:<ruby><rb>汉</rb><rt>hàn</rt></ruby>
-
<rb>不可省略,它是语义锚点,告诉浏览器“这个字要被注音” - 一个
<rb>只能对应一个<rt>,不能<rb>你好</rb><rt>nǐ hǎo</rt> - 多字必须拆开:
<ruby><rb>你</rb><rt>nǐ</rt></ruby><ruby><rb>好</rb><rt>hǎo</rt></ruby> - 如果还要兼容 IE8–,加
<rp>(</rp>和<rp>)</rp>,现代项目可跳过
拼音填进
填错格式会导致 <rt> 内容被截断、换行错位,甚至被浏览器忽略。常见翻车点不是逻辑,而是字符细节。
- 必须用半角小写字母,声调优先用 Unicode 字符(如
hàn),不用数字标调(han4)——后者语音引擎常无法识别变调规则 - 禁用全角空格、中文冒号、连字符;
nǐ-hǎo或nǐ:hǎo会让部分 WebView 把拼音切掉一半 - 轻声、儿化音写全:「我们」是
wǒ men,不是wǒ mén;「一会儿」得拆成三个<rt>:yí、huì、ér - 多音字不自动选音:「重」在「重庆」中读
chóng,必须人工判断并填入,pypinyin默认返回zhòng,直接套用就错
CSS 不设就等于没写 ruby
即使 HTML 结构完全正确,没加基础 CSS,<rt> 仍可能被截断、偏移、换行,或和汉字挤成一团。浏览器默认样式只提供基础语义,不保证可用排版。
立即学习“前端免费学习笔记(深入)”;
-
rt { font-size: 0.6em; }—— 用相对单位,避免固定像素在缩放时失衡 -
ruby { line-height: 1.6; }—— 防止基字行高被压缩,导致拼音被上一行遮挡 -
ruby { white-space: nowrap; }—— 强制字-音对不被断行拆开,尤其在窄屏或小字号下 - 避免用
vertical-align或top硬调位置——会破坏屏幕阅读器对注音关系的识别
动态生成时最容易漏掉的三件事
用 JavaScript 或服务端模板(如 Ruby、Jinja)批量生成 <ruby>,比手写更容易出隐性错误,且上线后难排查。
- 变量插值时引号冲突:Ruby 中别用双引号拼接含单引号的拼音(如
d'après),改用%Q{...}避免转义混乱 - 外部 API 返回拼音是数组(如
pinyin("你好") → ["nǐ", "hǎo"]),必须.join(' '),不能直接塞进<rt> - 绝对不要对整个字符串做
CGI.escapeHTML或DOMPurify.sanitize—— 它会把<rt>变成<rt></rt>,标签彻底失效
最麻烦的不是写错一次,而是结构看似正常、局部生效,但换浏览器或升级版本后突然崩——因为不同引擎对“宽容解析”的边界在变。真要稳妥,就得老老实实写 <rb>,老老实实设 line-height,老老实实逐字拆。



















