lang属性必须写在<html>标签上,其他位置全无效;中文应选zh-CN,因其明确简体中文与中国大陆规范,兼容屏幕阅读器、SEO及翻译工具最佳;多语言混排需在子元素显式标注lang,JS动态修改无效。

lang 属性必须写在 <html> 标签上,其他位置全无效
浏览器、屏幕阅读器(NVDA/JAWS/VoiceOver)、Chrome 翻译按钮、Google SEO 都只读取 <html lang="zh-CN"> 这个位置的值。写在 <body>、<div> 或 <meta> 里,对页面主语言声明完全没用。
常见错误现象:
– <body lang="zh-CN"> → 不被识别为文档语言,仅影响极少数 CSS :lang() 匹配
– <meta http-equiv="Content-Language" content="zh-CN"> → HTML5 已废弃,所有现代浏览器静默忽略
– <html lang=""> 或 <html lang="zh"> → 被视为“未知语言”,VoiceOver 可能直接 fallback 到英文 TTS 引擎读中文
中文该选 zh-CN 还是 zh-Hans 或 zh
三者语义和兼容性差异显著,不能混用:
-
zh-CN:事实标准,明确“简体中文 + 中国大陆规范”,NVDA、Chrome、百度/Google SEO 全链路支持最稳;字体回退、拼音方案、声调处理最全 -
zh-Hans:只表示“简体字”,未绑定地域;部分旧版 Safari 或翻译插件可能无法匹配正确语音模型 -
zh:过于宽泛,不区分简繁、不指明区域;iOS VoiceOver 可能跳过中文 TTS 引擎,把“行”读成 /hæŋ/ 而非 /xíng/
绝对避免:zh_china、zh_CN(下划线非法)、Chinese——全部被静默忽略。
多语言混排时怎么让屏幕阅读器“切换语种”
<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">包裹多个段落——<div>无语义,读屏不认,还可能干扰父级:lang(zh)CSS 匹配
动态页面中改 document.documentElement.lang 为什么经常白忙活
屏幕阅读器在 DOM 解析初期就读取 <html> 的 lang,后续 JS 修改(如 document.documentElement.lang = "en-US")不会触发语音引擎重载或重新分析文本:
- SPA 多语言切换不能只靠 JS patch,必须服务端渲染(SSR)或静态生成(SSG)不同
lang的 HTML 文件 - Next.js:确保
app/layout.tsx中<html lang={locale}>的locale来自路由或配置,而非客户端 hydrate 后才注入 - 纯前端切换若必须用 JS,至少同步改
<html>和所有已渲染的lang子元素,并触发aria-live提示;但已激活的朗读会话大概率不会响应
最容易被忽略的是:第三方组件库(如 Ant Design)内部文案不读取页面 lang,而是依赖自己配置的 locale——光设 <html lang="ja"> 不会让弹窗变日文。



















