lang属性必须写在标签上,其他位置无效;局部多语言内容需显式标注lang值;动态切换语言时须同步更新所有DOM节点的lang属性。

lang 属性必须写在 标签上,其他位置无效——这是浏览器、屏幕阅读器和搜索引擎识别页面主语言的唯一依据。只改 body 或某个 div 的 lang,等于没设。
为什么 不能写在 里
浏览器解析 HTML 时,在 DOM 构建初期就锁定根语言上下文; 这类写法被完全忽略,页面会被当作“无语言声明”处理。
- Chrome 自动翻译按钮不出现,或点击后乱翻成日语/韩语
- VoiceOver / NVDA 按系统默认语言(比如英文)朗读中文内容,声调错乱
- Google 搜索结果页显示“未指定语言”,多语言站点 SEO 权重下降
-
:lang(zh-CN)CSS 伪类无法匹配,导致中文标点挤压、避头尾等排版规则失效
局部多语言内容必须显式标注 lang,不能靠继承
浏览器不会自动推断「这段英文是引用」「这行代码注释是西班牙语」——每个含混排语言的节点,都得自己带 lang 值。
- 中文文档里嵌法语引文:
<blockquote lang="fr">Merci</blockquote> - 技术文档中夹英文代码说明:
<pre class="brush:php;toolbar:false;" lang="en"># Initialize counter</pre>(别写lang="bash",它不是 BCP 47 语言码) - 术语混排:
<p>我们使用 <code lang="en">React Router实现路由
Wechat Article Html下载将 Markdown 文章转换为微信公众号兼容的纯 HTML 格式。当用户要求"转成微信格式"、"生成公众号文章 HTML"、"排版到微信草稿箱"、"微信粘贴格式"时触发。输出带内联样式的纯 HTML,微信编辑器可直接渲染,无需额外适配。支持标题、段落、列表、粗体、行内代码、表格、引用块、代码块、配图的完整转换。
立即学习“前端免费学习笔记(深入)”;
- 错误做法:给整个
<section></section>加lang="en",再在里面放中文段落——中文部分仍按根语言渲染,字体 fallback 异常
动态页面(SPA)切换语言时,document.documentElement.lang 不够用
只执行 document.documentElement.lang = "ja-JP",已渲染的 DOM 节点语言上下文不会更新,屏幕阅读器、拼写检查、字体引擎全卡在旧状态。
- 必须同步遍历并更新所有已存在的
lang属性节点,包括<p lang="en"></p>、<blockquote lang="fr"></blockquote>等 - 第三方组件库(如 Ant Design)内部文案不响应
html的lang,需单独配置其locale,两者无自动联动 - 服务端渲染(Next.js/Nuxt)应在 HTML 初始响应中输出正确
lang,JS 补救是次选,且仅限首屏加载后立即执行 - 切语言后建议触发一次
document.title = document.title,强制辅助技术重读根节点
lang 值必须严格符合 BCP 47,大小写和分隔符错一个就失效
浏览器静默忽略非法值,但后果严重:语音引擎降级、CSS :lang() 不匹配、SEO 当作未标注。
- ✅ 推荐写法:
zh-CN(大陆简体)、zh-TW(台湾繁体)、en-US、pt-BR - ❌ 常见错误:
zh_CN(下划线)、ZH-CN(大写)、chinese(非 ISO 码)、zh-Hans-CN(冗余三段式,IANA 不推荐) - 别用
<meta http-equiv="Content-Language">—— HTML5 已弃用,所有现代浏览器忽略 -
hreflang和lang完全无关:hreflang是给搜索引擎看的链接关系,lang是给浏览器和辅助技术看的内容语言
最易被忽略的点:语言切换后,lang 属性必须同步更新到每一个相关 DOM 节点,而不是只改根元素;否则可访问性链路从第一层就断了,后续所有优化都白做。


















