混合语言内容需为每个外文元素显式设置精确的lang属性,根标签lang="zh-cn"仅定义主语言,不继承给嵌入内容;正确做法是在最小语义容器上标注对应语言值,如、等,并避免使用不匹配的:lang()伪类。

混合语言内容必须为每个外文元素显式加 lang 属性
根标签的 lang="zh-CN" 只定义主语言,对嵌入的英文、日文、法文等内容完全不生效。屏幕阅读器会用中文规则硬读英文单词,比如把 API 读成“阿皮”,而不是 /ˈeɪ.piː.ˈaɪ/。浏览器也不会触发翻译按钮或启用对应语言的拼写检查。
正确做法是:在实际使用该语言的最小语义容器上直接写 lang,且值要精确匹配内容本身:
-
<p lang="en">The response status is 404.</p>✅ 段落级英文 -
<blockquote lang="fr">La vie est belle.</blockquote>✅ 引文语义明确,读屏优先识别 -
<td lang="ja">東京</td>✅ 表格单元格必须单独标注,<table lang="en"> 不继承<li> <code><span lang="en">React</span>✅ 单词或短语级混排,避免用<div> 包裹——<code><div> 无语言语义<h3> <code>:lang()伪类匹配时,lang值必须严格对应CSS 中的
:lang(en)只匹配lang="en",不匹配lang="en-US"或lang="en-GB";同理:lang(zh)完全不匹配lang="zh-CN"。这是最常踩的坑:样式写了却没生效,不是语法错,而是值不一致。稳妥方案是用属性选择器前缀匹配:
-
[lang|="en"] { font-family: Arial, sans-serif; }→ 匹配en、en-US、en-GB -
[lang|="zh"] { font-family: "Microsoft YaHei", sans-serif; }→ 匹配zh-CN、zh-Hans、zh-TW - 避免只写
:lang(zh)——lang="zh"本身就不合法,现代读屏基本无视
表格、代码块、引文等特殊场景的
lang写法这些结构有隐含语义,
lang位置和取值稍有不同,错一处就影响可访问性:- 表格单元格:
<td lang="en">v1.2.0</td>,不能写在<tr> 或 <code><table> 上,也不要用 <code><div> 套一层再设 <code>lang - 代码注释:
<pre class="brush:php;toolbar:false;" lang="en"># Initialize counter</pre>,不是lang="bash"——lang描述内容语言,不是编程语言 - 引用类标签优先于
<span></span>:<q lang="de">Danke schön</q>比<span lang="de">Danke schön</span>更易被读屏识别为独立语言单元 - 中英混排的标题:
<h2 lang="zh-CN">快速开始(Quick Start)</h2>是错的——整句不是纯中文,应拆开:<h2>快速开始<span lang="en">Quick Start</span> </h2> - 服务端渲染(SSR)或静态生成(SSG):Next.js 在
app/layout.tsx中用;Nuxt 用useLocaleHead()输出到首屏 HTML - 多语言站点必须产出多个 HTML 入口文件,如
/zh/index.html(含)和/en/index.html(含),不能共用一个 HTML 再靠 JS 切换
动态页面里
lang不能靠 JS 后期设置React/Vue 等框架若只在组件挂载后执行
document.documentElement.lang = "en-US",对屏幕阅读器、浏览器翻译、SEO 全无效。因为这些系统只在 HTML 初始解析阶段读取,JS 执行时早已错过时机。真正有效的方案只有两种:
用户切换语言时,只改文案不改
,会导致语音朗读引擎卡在旧语言、浏览器翻译按钮持续误判——这个细节,90% 的前端项目都漏掉。 -











