lang属性必须写在<html>标签上,其他位置无效;中文推荐用zh-CN,多语言混排需显式标注子元素lang,JS动态修改无效。

lang 属性必须写在 <html> 标签上,其他位置无效——这是所有问题的起点。写错位置、写错值、写完再用 JS 改,都会让屏幕阅读器“听不懂”,翻译按钮“不出来”,搜索引擎“认不出”。
lang 属性只能写在 <html> 标签上
浏览器和读屏软件(NVDA、VoiceOver)只在解析 HTML 初始结构时读取 <html lang="...">,之后任何修改都晚了。
-
<body lang="zh-CN">→ 不被识别为文档语言,仅影响该<body>内部子元素的局部行为(极弱) -
<div lang="en">→ 可用于局部英文段落,但不能替代主语言声明 -
<meta http-equiv="Content-Language" content="zh-CN">→ HTML5 已弃用,Chrome/Firefox/Safari 全部忽略 -
<html lang="">或<html lang="zh">→ 空值视为“未知语言”,zh过于宽泛,部分旧版 VoiceOver 会直接 fallback 到英文 TTS
中文该用 zh-CN 还是 zh-Hans 或 zh
三者语义不同,兼容性差异明显,选错会影响断词、字体回退、CSS 匹配甚至 SEO。
-
zh-CN:事实标准,明确“简体中文 + 中国大陆规范”,NVDA/JAWS/VoiceOver/Chrome 全部稳定支持,CMS 和翻译插件默认认它 -
zh-Hans:强调“简体字”,不绑定地域,适合港澳台用户也用简体的场景;但旧版 Safari 的:lang(zh)可能匹配不准 -
zh:不区分简繁、不指明区域,Google Search Console 可能报“未指定语言”,iOS VoiceOver 可能跳过中文引擎硬读多音字 - 别写
zh_china、zh_CN、Chinese—— 全部非法,会被静默忽略
多语言混排时怎么让 lang 真正起作用
主语言靠 <html lang="zh-CN"> 确立,但嵌入的英文术语、日文引用、代码注释等,必须显式标注子元素的 lang,否则读屏仍用中文规则硬读。
立即学习“前端免费学习笔记(深入)”;
- 单个外文词:
<span lang="en">API</span>→ 读作 /ˈeɪ.piː.ˈaɪ/,不是“阿皮” - 整段英文:
<p lang="en">This is a code example.</p> - 代码块注释:
<pre lang="en"># Initialize counter</pre>(注意不是lang="bash") - 避免滥用:
<div lang="en">包裹多个段落 —— 语义不清,且可能干扰父级:lang(zh)CSS 匹配 -
<title>和alt属性无法嵌套标签,目前无标准解法;含多语言标题时,优先保证主体内容语言准确
动态页面中设置 lang 容易踩的坑
JS 动态改 document.documentElement.lang 对已加载页面基本无效——读屏不会重载语音引擎,搜索引擎不会重新索引,CSS :lang() 规则也不会重新计算。
- Next.js/Nuxt:必须在
app/layout.tsx或_document.tsx中注入lang,确保首屏 HTML 响应中就存在 - PHP 模板:
<html lang="<?php echo htmlspecialchars($lang, ENT_QUOTES); ?>">,防 XSS - 纯前端 SPA:若支持多语言,必须用 SSR 或 SSG 产出不同
lang的 HTML 入口文件,不能靠 JS patch - 第三方组件库(如 Ant Design)内部文案、日期格式化不读取
<html lang>,而是依赖自己配置的locale—— 光设lang不会让弹窗变日文
最常被忽略的一点:即使 <html lang="zh-CN"> 写对了,如果页面里大量英文术语、代码块、SVG 文本没加 lang 标注,辅助技术仍可能误判语种。真正有效的语言声明,得配合语义化标记一起用。



















