根本原因是lang属性必须写在html根标签且值符合bcp 47标准,如en-us;写在body、meta或js动态设置均无效,错误值如english、en-us会被静默降级为und。

为什么写了 lang="en" 但 Chrome 还是不显示“翻译成英文”按钮
根本原因不是没写,而是写错了位置或值。浏览器只认 这个声明,写在 、<meta> 或用 JS 动态设置都无效。常见错误包括:
-
—— 对翻译按钮完全无影响,只影响极少数 CSS:lang()匹配 -
<meta http-equiv="Content-Language" content="en">—— HTML5 已废弃,所有现代浏览器直接忽略 -
document.documentElement.lang = "en"—— 首屏 HTML 已解析完毕,翻译入口早已关闭,JS 补救不了 -
lang="english"或lang="EN"—— 不符合 BCP 47,被静默降级为und(未知语言)
en-US 和 en-GB 到底该选哪个
二者都合法,但语义和实际效果有差异:
-
en-US是绝大多数英文站点事实标准,Chrome、Safari、NVDA 全链路支持最稳,字体 fallback、标点间距、语音合成(TTS)都按美式规则处理 -
en-GB适合明确面向英国用户的内容,比如日期格式、拼写(colour vs color)、货币符号;但部分旧版读屏可能 fallback 到en-USTTS 引擎 - 绝对避免
en_us(下划线非法)、EN-us(大小写错位)、english(非标准标签)——全部被忽略 - 如果只是通用英文内容,无地域倾向,
en-US比en更可靠:en太宽泛,某些 iOS VoiceOver 版本会跳过英文 TTS 直接读音节
英文引文、代码注释里要不要加 lang
要,但必须语义合理、不滥用:
- 引文类元素显式标注更有效:
<blockquote lang="en">The only way to do great work is to love what you do.</blockquote>—— VoiceOver 会切换英文语调朗读 - 代码块中注释是英文时,建议用
<pre class="brush:php;toolbar:false;" lang="en"></pre>而不是<pre class="brush:php;toolbar:false;" lang="bash"></pre>——bash不是 BCP 47 语言标签,浏览器无法识别其语言意图 -
<code lang="en">useState可触发部分 IDE 的英文高亮逻辑,也利于语法分析工具识别上下文 - 别给每个英文单词都套
span lang="en"—— DOM 膨胀、可访问性树构建变慢,且多数读屏不响应这种细粒度标注
SPA 切换英文语言时,lang 改了但语音朗读还是中文
关键点在于:屏幕阅读器在页面加载初期就读取并缓存了 document.documentElement.lang,后续 JS 修改对已激活的朗读会话基本无效。
- 仅执行
document.documentElement.lang = "en-US"不够,必须同步触发重读根节点,例如:document.title = document.title(空赋值)能强制 VoiceOver/NVDA 重新解析 - 更稳妥的做法是服务端渲染(SSR)或静态生成(SSG)阶段就输出正确的
—— Next.js 在app/layout.tsx中用,Remix 在root.tsx中同理 - 若必须 CSR,需确保所有动态插入的文本节点(如 i18n hook 渲染的内容)也携带
lang属性,否则读屏仍按zh-CN规则硬读英文词
lang="en-US" 写对,而是让每一段 JS 渲染出来的文本、每一个第三方组件注入的 DOM、甚至 <title></title> 里的混排字符串,都在首次解析时就带着准确的语言上下文。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











