必须在首屏HTML中写对lang值且与页面主体语言完全一致,JS后期修改无效;需严格遵循BCP 47规范(如zh-CN),SSR服务端注入、静态站硬编码、SPA应整页刷新,并为局部外文内容显式标注lang。

必须在首屏 HTML 中写对 lang 值,且与页面主体语言完全一致——JS 后期修改无效,不匹配会直接导致屏幕阅读器误读、翻译错乱、SEO 降级。
检查并修正 <html lang="..."> 的初始值
浏览器和辅助技术只读取初始 HTML 的 <html> 标签中的 lang,后续任何 JS 修改(如 document.documentElement.lang = "en")都不会触发重解析。
- SSR 或服务端渲染项目:根据
Accept-Language请求头或用户登录态,在模板中直接注入正确值,例如<html lang="zh-CN"> - 静态站点(Hugo/Jekyll 等):每个语言版本生成独立 HTML 文件,
lang必须硬编码进模板,不可留空或写死为默认值 - 纯前端 SPA:语言切换时应整页刷新(
window.location.href),而非仅改属性;强行用outerHTML重写有 ARIA 缓存残留风险 - 验证方式:禁用 JS 后查看源码,确认
<html lang="zh-CN">出现在首行,且值与页面所有可见文案(按钮、提示、占位符、错误信息)语言一致
识别并修复常见不一致现象
不一致不是“看起来像中文就行”,而是语义层面的错配。典型表现包括:
- Chrome 地址栏出现“翻译成中文”按钮,点开后把中文翻成英文(因
lang="en"被误判为英文页) - NVDA/VoiceOver 用英语语音引擎读中文,把“软件”读成 /ˈsɒf.t.wɛər/
- Lighthouse 报告“
lang属性与页面内容不匹配”,归类为可访问性问题 - CSS
:lang(zh)规则完全不生效,中文字体 fallback 或标点挤压失效
根本原因往往是开发阶段残留英文文案(如 Vue 组件里写死的 "Loading...")、第三方 UI 库未传 locale: 'zh-CN'、或 Ajax 返回的 JSON 中混有英文字段名当显示文案用。
立即学习“前端免费学习笔记(深入)”;
局部多语言内容必须显式标注 lang
<html lang="zh-CN"> 只定义主语言,不影响嵌入的外文内容识别。这些节点若不单独声明 lang,屏幕阅读器仍按中文规则硬读。
- 单个术语:
<span lang="en">API</span>→ 读作 /ˈeɪ.piː.ˈaɪ/,不是“阿皮” - 代码块注释:
<pre lang="en"># Initialize counter</pre>(别用lang="bash",BCP 47 不认) - 引文类语义标签更可靠:
<blockquote lang="ja">こんにちは</blockquote> - 表格单元格需逐个标注:
<td lang="en">iPhone 15 Pro</td>、<td lang="zh-Hans">超视网膜XDR显示屏</td> - 避免套壳写法:
<td><div lang="ja">東京</div></td>无效——<div>没有语言语义,必须直接写在<td>上
验证 BCP 47 格式是否严格合规
写错 lang 值浏览器不报错,但等于没写:搜索引擎忽略、屏幕阅读器朗读错、:lang() 完全不匹配。
- ✅ 正确写法(区分大小写、短横线):
zh-CN、en-US、pt-BR、zh-Hans - ❌ 典型错误:
zh_CN(下划线→静默降级为und)、ZH-cn(大小写混用→部分 iOS VoiceOver 失效)、Chinese(非标准值,被全部忽略) - 选
zh-CN还是zh-Hans?多数 CMS、SEO 工具、翻译插件只认zh-CN;zh-Hans仅当你明确排除港澳台繁体、且需强调“简体字”时才用 - 不要用三段式如
zh-Hans-CN:IANA 不收录,Chrome 会静默降级为zh
最容易被忽略的是动态生成内容——lang 再准,Ajax 返回的 JSON 若带英文文案,或 React 组件里写死的 "Submit",照样造成事实不一致。



















