lang属性必须逐元素声明且符合bcp 47标准,否则导致字体回退失效、屏幕阅读器发音错误、浏览器翻译跳过、css :lang()选择器不匹配;根标签lang仅定义主语言,内嵌多语言内容须各自声明,spa中需同步更新所有节点lang值。

lang 属性写错或漏写,多语言混排时字体回退、屏幕阅读器发音、浏览器翻译全部失效——不是“效果不好”,是直接跳过或读错。
lang 属性必须逐元素声明,不能只靠 html 根标签
根标签 只定义文档主语言,对内嵌的英文术语、日文引用、代码块(如 curl -X POST)完全不生效。这些内容必须各自带 lang,否则:
- 屏幕阅读器继续用中文引擎读
<p>API endpoint</p>,发音生硬甚至错误 - Chrome 右键“翻译成中文”会跳过该段落,因为没声明
lang="en" - CSS 的
:lang(ja)选择器无法匹配到<blockquote></blockquote>内的日文,样式不触发
正确写法示例:<p>调用 <code lang="bash">npm run build 后,检查 exit code 是否为 0
BCP 47 语言标签写错,等于没写
值不符合标准,会导致字体加载异常、拼写检查关闭、甚至 SSR 框架拒绝渲染。常见错误包括:
-
zh_CN(下划线非法)→ 改为zh-Hans -
chinese(非标准子标签)→ 改为zh-Hans或zh-Hant -
zh(太宽泛)→ 无法区分简繁,影响字体链和排版规则 -
lang="bash"虽非真实语言,但被语法高亮工具识别,可安全使用
验证建议:用 Intl.getCanonicalLocales("zh-CN") 浏览器控制台跑一下,看是否返回标准化格式。
多语言混排时 CSS 排版依赖 :lang(),不是 [lang]
想让日文标点自动加间距、阿拉伯文右对齐、中英文混排时行高一致,必须用 :lang(ja) 这类伪类:
-
[lang="ja"]只匹配显式写了lang="ja"的元素本身,不继承 -
:lang(ja)匹配该元素或其任意祖先有lang="ja",适合处理嵌套文本 - 字体链也受此影响:Chrome 对
lang="ja"元素优先加载日文字体,lang="zh-Hans"触发中文字体回退逻辑
示例:
q:lang(ja) { quotes: "「" "」" "『" "』"; }<br>
:lang(ar) { direction: rtl; text-align: right; }
SPA 动态切换语言时,只改 document.documentElement.lang 不够
单页应用里执行 document.documentElement.lang = "en" 后,新渲染节点能读对,但已有 DOM(尤其是富文本、第三方组件插入的内容)仍按旧 lang 解析:
-
<blockquote lang="fr"></blockquote>不会自动更新,屏幕阅读器继续用法语引擎读 - 如果用了
data-i18n+ JSON 翻译方案,得同步重刷textContent,否则lang值虽对,内容还是中文 - 第三方库(如 Markdown 渲染器)生成的
<code lang="python">需手动遍历并重设
真正要动的不是根节点,而是所有含语言信息的节点——尤其容易被忽略的是服务端注入的 HTML 片段,它们不会响应前端 lang 变更。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











