必须在标签上写对lang,否则屏幕阅读器直接fallback英文引擎;只认,因nvda、voiceover等仅在初始解析时读取该属性初始化语音引擎,其他位置无效,且lang值须严格符合bcp 47(如zh-cn、zh-tw),非法值将被静默忽略或导致误读。

必须在 标签上写对 lang,否则屏幕阅读器根本不会按你预期的语言读——不是“效果差”,而是直接 fallback 到英文引擎,中文被逐字拼读成 “B-e-i-j-i-n-g”。
为什么只认 这一个地方
NVDA、VoiceOver、JAWS 这些主流屏幕阅读器,只在页面初始解析时扫描 元素的 lang 属性,用它初始化整页语音引擎。其他位置写了等于白写:
-
—— 不触发全局语言切换,仅作局部覆盖(且需配合子元素才生效) <div lang="ja"> —— 有效,但前提是外层没阻断继承(比如父级用了 <code>aria-hidden="true")-
<meta http-equiv="Content-Language">—— HTML5 中已废弃,完全不被识别 -
lang="zh":BCP 47 不合规,多数 AT 拒绝加载中文 TTS,fallback 英文 -
lang="zh_CN":下划线非法,浏览器静默忽略,等效于无lang -
lang="chinese":非标准标签,完全不识别 -
lang="zh-CN ":末尾空格导致解析失败,Lighthouse 报invalid language subtag - 单个外文词:
<span lang="en">API</span>—— 触发英文音素切分,读作 “A-P-I” 而非 “阿皮” - 技术标识符:
<code lang="en">fetch()—— 比<span></span>更语义准确,部分读屏对<code>有特殊停顿处理 - 整段英文:
<p lang="en">The response is a JSON object.</p>—— 避免用<div lang="en"> 包多段,语义不清且干扰 <code>:lang(en)CSS 选择器 - SVG 中的
<title></title>、表单placeholder、JS 动态插入文本 —— 这些都出现在 DOM 中,同样需要对应lang或aria-label补救 - SSR 场景下,首屏 HTML 必须带正确
lang,否则爬虫和首屏读屏拿到的就是错的 - 服务端模板中用
lang="{{ locale }}",必须过滤非法值(如后端返回"zh"就得兜底成"zh-CN") - 不要依赖 JS 在
onload里补lang—— 用户已经听到错误发音了,补也没用
lang 值写错比不写更危险
错标会导致分词错、声调错、标点停顿全乱,用户听不懂。常见非法值及后果:
真正可用的只有:zh-CN(简体大陆)、zh-TW(繁体台湾)、zh-HK(繁体港澳)。zh-Hans 虽合法,但旧版 JAWS 可能词典匹配不全。
中英文混排时,局部 lang 怎么嵌套才不翻车
根 lang="zh-CN" 只管默认行为;遇到英文术语、代码、引文,必须显式标注,否则会被硬读成中文音:
React/Vue 里动态设 lang 为什么总是晚一步
执行 document.documentElement.lang = "en-US" 只影响后续插入的 DOM 节点,对已渲染内容、已挂载组件、已计算的 CSS 伪类(如 :lang(en))完全无效:
最麻烦的不是写错,而是写了但没在真实 AT 上测过;NVDA 和 VoiceOver 对嵌套 lang 的解析深度不一致,三层以上切换可能让某些读屏缓存混乱。











