所有HTML页面必须设置lang属性,未设置将导致翻译功能失效、屏幕阅读器误读、搜索引擎降权、CSS断行失效;lang值须符合BCP 47标准(如zh-CN),大小写错误或非法标签会被浏览器忽略;SPA需在首屏HTML中静态声明,局部多语言内容须显式标注。

所有 HTML 页面都必须设置 lang 属性,不存在“是否需要”的判断——没设,就是错的。
不设 lang 会直接触发可访问性与功能降级
浏览器、搜索引擎、屏幕阅读器(NVDA/VoiceOver/JAWS)在解析 HTML 的第一毫秒就依赖 document.documentElement.lang 做决策。没这个值,后果是确定且即时的:
- Chrome 右键菜单不显示「翻译成中文」选项
- NVDA 把「北京」读成 /bɛɪˈdʒɪŋ/(英语音),而非 /pei³⁵ tɕiŋ⁵⁵/(普通话)
- Google Search Console 标记「未声明页面语言」,影响中文页在百度/谷歌的索引权重
- CSS 的
hyphens: auto完全失效,中文无法自动断行,英文连字符也不触发
lang 值写错比不写更危险
常见非法或弱效写法会导致浏览器静默忽略,等同于没设:
-
lang="zh":BCP 47 不推荐,iOS VoiceOver 可能跳过中文 TTS 引擎 -
lang="ZH-CN"或lang="zh_CN":大小写混用、下划线非法,被 Chrome/Firefox/Safari 直接丢弃 -
lang="chinese"或lang="cn":非标准标签,完全无效 -
:只影响局部断词,对整页语言识别零作用
动态页面里,lang 必须在首屏 HTML 中存在
React/Vue 等 SPA 框架常犯的错误是:等 JS 加载完再执行 document.documentElement.lang = "ja-JP"。此时已晚——屏幕阅读器早已初始化语音引擎,翻译按钮也已渲染完毕。
立即学习“前端免费学习笔记(深入)”;
- Next.js:必须在
app/layout.tsx中用,locale来自路由参数或配置 - Nuxt:用
useLocaleHead(),确保 SSR 输出真实lang值 - 纯 CSR 应用:若支持多语言,必须生成多个静态 HTML 入口(如
/zh/index.html、/en/index.html),每个含对应硬编码
局部多语言内容不是靠猜,而是靠显式标注
根元素 lang="zh-CN" 只解决主语言基调。一旦出现外文段落、代码注释、品牌名或引文,就必须手动加 lang:
- 整段英文:
<p lang="en">This is not translated.</p> - 法语引文:
<blockquote lang="fr">Merci beaucoup.</blockquote> - 代码标识符:
<code lang="en">useState(不是lang="javascript") - 避免滥用:
<div lang="en">...</div>包裹大段内容——语义不清,干扰:lang(zh)CSS 匹配
真正难的不是写对一个 lang="zh-CN",而是让每个通过 innerHTML 插入、第三方 SDK 渲染、iframe 跨域加载的文本节点,都带着准确的语言上下文被解析——这需要从模板层、组件层、甚至第三方脚本集成时就设计好语言继承链。



















