必须用<rb>显式包裹每个被注音字,否则现代浏览器忽略<rt>;多字需逐字拆分;<rp>是降级保底必需项;CSS仅限调整font-size和line-height;批量注音须用工具生成合法结构。

必须用 <rb> 显式包裹每个被注音字,否则现代浏览器(Chrome 120+、Firefox 125+、Safari 17+)会忽略 <rt>,直接平铺显示“汉字拼音”——这不是样式问题,是语义缺失导致的渲染失败。
为什么写了 <ruby>汉<rt>hàn</rt></ruby> 却不显示拼音
这是最常踩的坑:结构看似完整,实则缺了关键角色 <rb>。现代浏览器已不再容忍“隐式基字”,<rb> 是唯一被识别为“被注音对象”的元素。
-
<ruby>汉<rt>hàn</rt></ruby>→ 浏览器降级为纯文本“汉hàn”,<rt>被当作普通内联内容 -
<ruby><rb>汉</rb><rt>hàn</rt></ruby>→ 正确,<rb>和<rt>紧邻成对,语义明确 - 多字必须逐字拆开:
<ruby><rb>北</rb><rt>běi</rt><rb>京</rb><rt>jīng</rt></ruby>,不能合写<rb>北京</rb><rt>běi jīng</rt>
<rp> 不是可选项,而是降级保底的必要开关
<rp> 的作用不是装饰,是在 IE11、Outlook Desktop、老旧 Android WebView 等环境里兜底显示括号格式(如“汉(hàn)”)。没有它,这些环境只会裸露“汉hàn”,破坏可读性与无障碍支持。
- 正确写法必须成对:
<rp>(</rp><rt>hàn</rt><rp>)</rp>;单个<rp>无效 - 现代浏览器自动隐藏
<rp>内容,只渲染<rt>;老环境则忽略<ruby>和<rt>,仅显示括号内文字 - 若服务端无法保证所有字都有拼音,空
<rt></rt>必须避免——部分屏幕阅读器会朗读“空白注音”,造成干扰
CSS 微调只能动 font-size 和 line-height,其他都危险
浏览器对 <ruby> 的原生排版逻辑非常精细,强行覆盖会同时破坏视觉对齐、换行行为和屏幕阅读器语义顺序。
- 安全调整:
ruby { line-height: 1.8; }防止<rt>被基字压住;rt { font-size: 0.7em; color: #666; } - 禁用:
position: absolute、display: inline-block、vertical-align、white-space: nowrap——这些会让<rt>脱离基字定位,或导致长拼音横向溢出 - 需要拼音在下方?用
ruby { ruby-position: under; },别用 transform 翻转 - 旧版 Safari 对连续
<ruby>有轻微对齐偏移,仅当实际发生时加ruby { ruby-position: over; }重置
批量加拼音不能靠手写,得用工具生成合法结构
<ruby> 不解析汉字,也不调用拼音引擎。所有 <rt> 内容必须预先生成,且必须带 <rb>——手动拼错一个标签,整段注音就失效。
- 推荐
pinyin-pro(JS):import { html } from 'pinyin-pro'; const result = html('饕餮');→ 输出含<rb>、<rt>、<rp>的完整字符串 - Python 可用
pypinyin+ 模板拼接,但需确保每个字独立调用lazy_pinyin()并封装为<rb>字</rb><rt>拼音</rt> - 后端生成时,务必校验输出中每个
<rt>前紧邻一个<rb>,且无空格/换行/块级元素插入其中
真正难的不是写对一个字,而是让几百字的古籍注音在 Safari 换行、Edge 缩放、NVDA 朗读时全部保持字音一一对应——<rb> 是锚点,<rp> 是退路,其余全是克制。

















