lang属性必须写在<html>标签上,否则浏览器、屏幕阅读器、搜索引擎和Chrome翻译均无法识别页面主语言;正确值为zh-CN或en-US等BCP 47规范小写短横线格式,局部多语言内容需显式声明lang属性。

lang 属性必须写在 <html> 标签上,否则无效
浏览器、屏幕阅读器(如 NVDA、VoiceOver)、搜索引擎和 Chrome 翻译功能,全部只读取 <html lang="..."> 的值作为整页语言依据。写在 <body>、<div> 或任何子元素上,对主语言声明完全无作用——<title>、<meta name="description"> 这些关键语义内容会“失联”,导致语音朗读错、SEO 降权、翻译按钮不出现。
常见错误包括:<body lang="zh-CN">、<html lang="Chinese">、<html lang="zh_china">。这些写法要么被忽略,要么被当作文本错误处理。
用什么值?优先选 zh-CN 或 en-US,别用 zh 或 en
zh-CN 是简体中文的事实标准:覆盖拼音方案、声调模型、词典匹配最全,NVDA/JAWS/VoiceOver 全部稳定支持。zh 过于宽泛,iOS VoiceOver 可能 fallback 到英文 TTS;zh-Hans 仅表示“简体字”,不绑定地域,旧版 Edge 或某些翻译插件可能无法加载对应语音库。
所有值必须符合 BCP 47 规范,惯例小写、短横线分隔。以下全是非法值:zh_cn、ZH-CN、chinese、en-us(小写连字符虽不报错但易引发模板不一致)。
立即学习“前端免费学习笔记(深入)”;
- 服务端渲染时,根据
Accept-Language头动态输出<html lang="zh-CN"> - 静态页或 SSR 模板中,硬编码最稳,避免 JS 注入延迟导致闪动
- 后端返回
zh_ch或ZH-CN时,前端需统一转成小写+短横线格式再写入
局部多语言内容必须显式加 lang,不能靠继承
浏览器不会自动推断「这段是引用」「这行是代码注释」——它只认你明写的 lang。不加,就全按根语言处理:中文页面里嵌的 <p>This is English</p> 会被 VoiceOver 用中文规则硬读,拼写检查失效,字体 fallback 错乱(比如日文假名被塞进中文字体里显示为方块)。
Perplexity SEO 优化指南 — 如何获得 Perplexity AI 的引用。涵盖 Perplexity 引用行为、面向 Perplexity 答案的内容结构、Perplex...
正确做法是给目标元素显式声明:<blockquote lang="fr">Je suis français.</blockquote>、<pre lang="bash">curl -X POST</pre>、<code lang="en">useState</code>。
容易踩的坑:
- 只改
document.documentElement.lang = "ja-JP",已渲染的 DOM 不会重算语言行为 - 用
<div lang="en">包裹多个段落,破坏语义层级,干扰:lang(zh)CSS 匹配 - 给每个单词都加
lang,可访问性树构建变慢,DOM 体积无谓增大
JS 动态切换语言时,document.documentElement.lang 只影响新插入节点
屏幕阅读器在 DOM 解析初期就读取并缓存了 <html> 的初始 lang 值,后续 JS 修改不会触发语音引擎重载或文本重分析。已存在的 <p>こんにちは</p> 仍按旧 lang 解析。
如果真要做运行时语言切换(比如 demo 页),至少做到三件事:
- 在语言切换钩子中同步更新所有已存在元素的
lang属性,不只是根节点 - 对新增内容(如异步加载的卡片、弹窗)确保其
lang与当前语言一致 - 避免依赖
document.documentElement.lang做逻辑判断,应以真实 DOM 节点上的lang为准
真正难的不是设 lang,而是在组件化、国际化框架(如 i18n、react-intl)中保持 lang 属性与实际文本语言严格同步——尤其当文案来自 CMS、用户输入或翻译 API 时,很容易漏掉局部 lang 注入。这个细节没有报错提示,但一上线就影响无障碍合规和多语言 SEO。


















