lang属性必须正确设置在html根标签且符合BCP 47格式(如zh-CN),否则浏览器将降级为und并误判语言;多语言混排需局部显式标注,SPA切换语言需整页刷新或同步更新所有lang属性。

lang 属性本身不阻止误判,但写对了才能让浏览器“有据可依”——错写、漏写、乱写,浏览器就只能瞎猜。
为什么写了 lang 还被当成别的语言?
常见错误现象:html lang="zh_CN"(下划线)、lang="Chinese"(非标准值)、lang="zh"(太宽泛,iOS VoiceOver 可能跳过中文 TTS)、<body lang="zh-CN">(位置错,只影响 body 内文本,不声明整页语言)。
浏览器看到非法或模糊的 lang 值,会静默降级为 und(未知语言),然后靠字符分布、HTML 标签密度、甚至 URL 路径来“推测”——结果就是英文页面被当成中文翻译,日文引文被用中文模型重译一遍再翻回日文。
-
html根标签的lang是唯一被搜索引擎、屏幕阅读器、Chrome 翻译菜单真正信任的语言信号 - 所有其他位置(
body、div、meta http-equiv="Content-Language")都不算数,HTML5 已弃用后者 - 值必须严格小写 + 连字符 + BCP 47 格式:✅
zh-CN、en-US、ja-JP;❌ZH-cn、zh_cn、english
多语言混排时,局部 lang 怎么加才不翻车?
表格、代码块、引文这些地方,不能靠继承,必须显式打标。浏览器和读屏软件只认 td、pre、blockquote 自身的 lang 属性,不看父级。
立即学习“前端免费学习笔记(深入)”;
-
<td lang="en">API Key</td>✅ 正确标注英文术语,避免被拼音朗读 -
<pre lang="bash">curl -X POST</pre>❌ 错误:bash 不是语言,应改用lang="en"或留空;否则拼写检查、语音引擎全乱套 -
<blockquote lang="fr">C'est la vie.</blockquote>✅ 法语引文触发法语语音和词典校验 - 数值、日期、单位(如
2026-09-21、USD)不用加lang,它们无自然语言发音规则
SPA 切换语言后,为什么页面还是旧的发音/字体/翻译?
关键点:辅助技术在 HTML 解析初期就读取 document.documentElement.lang,JS 后期修改对已激活的朗读会话基本无效;已渲染的 DOM 也不会自动重触发翻译逻辑。
- 只改
document.documentElement.lang = "en"不够,必须同步更新所有已有元素的lang属性(比如遍历querySelectorAll("[lang]")) - 更稳妥的做法是整页刷新:
location.reload(),尤其当页面含第三方脚本生成的内容时 - 若必须单页切换,至少要强制重读根节点:
document.title = document.title(空赋值触发屏幕阅读器重读) - 服务端渲染(如 Next.js 的
app/layout.tsx)比客户端 JS 动态改lang更可靠
真正难的不是设对一个 lang="zh-CN",而是让每个动态插入、跨框架、第三方脚本生成的文本节点,都带着准确的语言上下文被解析——这需要从模板层、数据层、组件层统一约束,而不是靠 JS 补丁打满全栈。



















