lang属性必须写在标签上,浏览器、屏幕阅读器和搜索引擎仅依据根元素的lang值识别整页主语言;写在或子元素上仅影响局部语言处理,不改变页面级语言判定。

lang属性必须写在html>标签上,其他位置基本无效
浏览器、屏幕阅读器、搜索引擎只认根元素的 lang 值作为整页主语言依据。写在 、<div> 或任何子元素上,对页面级语言识别毫无作用——它只影响该元素及其后代的局部语言处理。
<p>常见错误现象:</p>
<ul>
<li>Chrome 自动翻译按钮不出现,或点开后把中文页错译成日语</li>
<li>屏幕阅读器把「行」读成 <strong>háng</strong>(按英文音节切分),而非 <strong>xíng</strong>(中文语义音)</li>
<li>Google 搜索结果页显示“未指定语言”,导致<a style="color:#f60; text-decoration:underline;" title="多语言" href="https://m.php.cn/zt/20151.html" target="_blank">多语言</a>站点 SEO 降权</li>
</ul>
<p>实操建议:</p>
<ul>
<li>SSR 页面:服务端根据 <code>Accept-Language 头或路由路径(如 /en/)直接输出
标签硬编码对应值,避免 JS 注入延迟导致闪动<meta http-equiv="Content-Language">:HTML5 已弃用,浏览器忽略局部多语言内容必须显式声明lang,不能靠继承
浏览器不会自动推断「这段英文是引用」「这行日文是代码注释」——它只认你明写的 lang 值。不加,就全按根语言处理,后果是语音朗读错、拼写检查失效、字体 fallback 异常(比如日文混排时用中文字体显示假名)。
使用场景举例:
- 中文文档里嵌法语引文:
<blockquote lang="fr">Je suis français.</blockquote> - 技术文档夹英文术语:
<code lang="en">useState可触发 IDE 插件英文高亮 -
<pre class="brush:php;toolbar:false;" lang="bash">curl -X POST</pre>:虽非标准语言码,但被语法高亮工具和浏览器识别为代码上下文
容易踩的坑:
- 给每个单词都加
lang:DOM 体积增大,可访问性树构建变慢 - 误以为
lang="ja"足够:iOS VoiceOver 某些版本会降级为英语发音,lang="ja-JP"更稳妥 - 后端返回
zh_ch或ZH-CN,前端没转成小写+短横线,导致lang值非法被忽略
lang值必须符合BCP 47标准,大小写与分隔符有严格要求
lang 值不是随便写的字符串。BCP 47 要求:语言子标签小写(如 zh、en),地区子标签推荐大写(如 CN、US),且必须用 ASCII 短横线 - 连接——下划线 _、全大写、全小写、Unicode 破折号全都不合法。
正确示例:
-
(简体中文,中国大陆) -
(繁体中文,中国台湾) -
(英式英语) -
(西班牙本土西班牙语)
错误写法(会被 Lighthouse、axe 等工具报错):
-
(下划线 ❌) -
(语言码大写 ❌) -
(地区码非标准 ❌)
SPA切换语言时,document.documentElement.lang只是起点
单页应用里改完 document.documentElement.lang,只是更新了根节点。已渲染的子元素仍保留旧的 lang 值,屏幕阅读器、拼写检查器、字体引擎全按各自当前的 lang 工作,不是看父级继承来的。
实操建议:
- 语言切换钩子中,不仅要执行
document.documentElement.lang = "ko-KR",还要同步遍历并更新所有含语言信息的节点,比如<p lang="en"></p>→<p lang="ko"></p> - 避免只改文案或 class:无障碍工具不读 class,只读
lang属性 - 强制刷新辅助技术上下文:改完后执行
document.title = document.title(空赋值),触发重新读取
最易被忽略的一点:hreflang 和 lang 没有自动关联。两者需独立维护,且必须一致——否则搜索引擎分流到英文页,但页面却写着 ,用户打开后字体错、标点挤、语音乱。











