只改document.documentelement.lang不够用,因为浏览器和屏幕阅读器不继承根节点lang,而是逐个检查各元素自身的lang属性来决定语音朗读、标点间距、字体回退等行为。

lang 属性不是“可有可无”的装饰,而是浏览器、屏幕阅读器、搜索引擎判断语言的唯一依据;不按规范设,国际化就只是表面切换,实际语音朗读错、标点乱、字体覆盖、SEO降权全都会发生。
为什么只改 document.documentElement.lang 不够用
浏览器和辅助技术只靠 判断整页主语言,但已渲染的 <p></p>、<h2></h2>、<label></label> 等元素完全不继承这个值——它们各自的语言行为由自身 lang 属性决定。
- 常见错误:SPA 切换语言时只执行
document.documentElement.lang = "ja-JP",却没更新已有 DOM 节点的lang,结果 VoiceOver 仍用中文引擎读日文假名 - 标点异常:没写
<p lang="zh-Hans">你好,世界</p>,中文顿号「、」会被当成英文 comma 渲染,间距过宽 - 字体回退失效:
<pre class="brush:php;toolbar:false;" lang="bash">npm install</pre>若被误设为lang="zh-Hans",等宽字体可能被中文字体覆盖,代码变模糊 - 正确做法:语言切换后,必须批量重写所有含文本语义化标签的
lang属性,包括<h1></h1>、<section></section>、<footer></footer>,但跳过<script></script>和<style></style>
lang 值必须严格符合 BCP 47 标准
写错格式等于没写。浏览器不纠错、不降级、不猜测,只做精确匹配。
- 有效写法:
zh-Hans、en-GB、ja-JP(小写字母 + 连字符 + 地区码) - 无效写法:
zh_cn(下划线)、ZH-HANS(大写)、zh-Hans(末尾空格)、Chinese(非标准标识符) - 容易踩的坑:后端返回
lang="zh_ch",前端未做标准化转换就直接赋给document.documentElement.lang,整页语言声明失效 - 繁简必须区分:
zh-Hans和zh-Hant触发不同的拼音标注逻辑与语音引擎,混用会导致 iOS VoiceOver 降级为英语发音
局部多语言内容必须显式标注 lang,不能靠“上下文推断”
浏览器不会自动识别「这是引用」「这是代码注释」。不加 lang,就全按根语言处理——拼写检查失效、语音错乱、字体 fallback 异常。
- 中文文档里嵌法语引文:
<blockquote lang="fr">Merci</blockquote> - 技术文档夹英文术语:
<code lang="en">useState,既保语义又利于 IDE 高亮 - 代码块保留原
lang:<pre class="brush:php;toolbar:false;" lang="bash">curl -X POST</pre>切换页面语言时,lang="bash"必须保留,这是合法混排,不是错误 - 避免滥用:
<div lang="zh-Hans"> 仅作样式容器?没必要。语义化标签(<code><p></p>、<section></section>)才需要,无文本的<div> 或 <code><span></span>加了也白加动态插入的 DOM 必须手动触发
lang更新AJAX 加载的弹窗、分页表格新行、Tab 面板内容插入后,
lang属性不会自动同步。它只是静态 HTML 字符串,不是响应式指令。- 常见错误现象:
<modal><h2 lang="zh-Hans" data-i18n="modal_title"></h2></modal>插入后,lang值仍是初始状态,没随当前语言更新 - 必须在
appendChild()或insertAdjacentHTML()后立即遍历新节点树,对每个含文本的语义化子元素重设lang - 推荐封装工具函数:
syncLang(node, currentLang),递归处理子节点,并跳过已有固定lang的特殊元素(如<pre class="brush:php;toolbar:false;" lang="bash"></pre>) - 注意边界:
<script></script>和<style></style>内部不用处理,它们不参与文本渲染,设了lang也没意义
最常被忽略的其实是“局部覆盖”的粒度——不是“整个页面切语言”,而是“每个可读文本块都有自己的语言身份”。这听起来琐碎,但正是屏幕阅读器、拼写检查、字体链、标点间距真正依赖的底层事实。
- 常见错误现象:











