表格单元格的 lang 属性必须直接写在 或 上,浏览器和屏幕阅读器不继承父级语言设置;混排内容需按实际语言分别标注,如 lang="en"、lang="zh-hans"、lang="ja";css :lang() 匹配需精确对应,推荐使用属性选择器前缀匹配。

表格单元格的 lang 属性必须直接写在 <td> 或 <code><th> 上
<p>浏览器和屏幕阅读器不会从 <code><table> 或 <code><tr> 继承语言意图,哪怕你给整张表加了 <code>lang="en",里面的中文单元格仍会被读作英文发音。只有显式写在 <td lang="zh-Hans"> 这类具体单元格标签上,才能触发正确朗读。
<p>常见错误是套一层 <code><div> 或 <code><span></span> 再设 lang:<td><div lang="ja">東京</div></td>——这没用。<div> 没有语言语义,读屏软件只认 <code><td> 自身的 <code>lang 值。
-
<td lang="ja">東京</td> ✅ 直接标注,有效
-
<td><span lang="ja">東京</span></td> ✅ <span></span> 是行内容器,支持 lang,且语义合理
-
<td><div lang="ja">東京</div></td> ❌ <div> 不传递语言意图
<li>
<code><table lang="en"><td>API</td></table> ❌ 表级 lang 不覆盖单元格内自然语言文本
中英文混排表格里,每个 <td> 的 lang 值要按实际内容选
<p>不能图省事全设成 <code>lang="zh-CN" 或统一用 lang="en"。比如一列是产品名(英文),一列是说明(中文),一列是日文备注——它们得各自声明:
<td lang="en">iPhone 15 Pro</td>
<td lang="zh-Hans">超视网膜XDR显示屏</td>
<td lang="ja">Proモード対応</td>
注意:zh-Hans 比 zh-CN 更稳妥,尤其当表格可能被港澳台用户访问时;ja 就足够,不需要写 ja-JP,除非你明确区分日本本土和海外日语变体。
- 数值、代码、符号(如
USD、2026-07-07)不需设 lang,它们无自然语言发音规则
- 缩写词如
API、UI 若出现在中文上下文中,建议包裹 <span lang="en">API</span>,否则读屏会按中文拼音硬读
- 避免在
<th> 上乱用 <code>lang="en" 只因为“看起来像英文”——如果标题实际是中文术语(如“用户ID”),就该用 lang="zh-Hans"
:lang() CSS 在表格里容易失效的两个原因
你写了 td:lang(zh-Hans) { font-family: "PingFang SC", sans-serif; } 却没生效?大概率卡在这两点:
-
:lang(zh-Hans) 是精确字符串匹配,<td lang="zh-CN"> 不会命中它;反过来也一样。别指望一个规则通吃所有中文变体
<li>表格单元格若含内联元素(如 <code><strong></strong>),而 lang 又只写在 <td> 上,那 <code>strong:lang(zh-Hans) 会失败——因为 <strong></strong> 自身没 lang,也不继承父级的 :lang() 匹配逻辑
更实用的做法是用属性选择器前缀匹配:td[lang^="zh"] 覆盖 zh-Hans、zh-CN、zh-Hant;或者干脆把字体规则写在 td 上,靠 lang 控制其他行为(如引号、断词)。
动态渲染表格时,lang 属性必须随内容一起注入
用 JS 拼接字符串或 Vue/React 渲染表格时,别漏掉 lang——它不是装饰性属性,而是可访问性刚需。常见坑:
-
innerHTML = <td>Bonjour</td> → 缺少 lang="fr",读屏仍读“帮朱瓦”
- Vue 中写
<td :lang="row.lang">{{ row.text }}</td>,但 row.lang 是空或非法值(如 "french"),会导致静默失效
- React 使用
dangerouslySetInnerHTML 时,若原始 HTML 字符串里没带 lang,JS 无法事后补救——必须源头生成时就带上
服务端模板(如 EJS、Twig)更可靠:直接把语言码从数据层透传到 <td lang="{{ cell.lang }}">。前端框架里建议把语言信息作为字段结构的一部分,而不是靠 guess 或 fallback。
<p>表格里最容易被忽略的是表头分组(<code><thead>)、跨列单元格(<code>colspan)和空单元格——只要里面含自然语言文本,哪怕只有一个词,就得标 lang。空 <td> 不用标,但 <code><td> </td> 如果是占位用的,也不需要。
<td lang="ja">東京</td> ✅ 直接标注,有效<td><span lang="ja">東京</span></td> ✅ <span></span> 是行内容器,支持 lang,且语义合理<td><div lang="ja">東京</div></td> ❌ <div> 不传递语言意图
<li>
<code><table lang="en"><td>API</td></table> ❌ 表级 lang 不覆盖单元格内自然语言文本中英文混排表格里,每个 <td> 的 lang 值要按实际内容选
<p>不能图省事全设成 <code>lang="zh-CN" 或统一用 lang="en"。比如一列是产品名(英文),一列是说明(中文),一列是日文备注——它们得各自声明:
<td lang="en">iPhone 15 Pro</td><td lang="zh-Hans">超视网膜XDR显示屏</td><td lang="ja">Proモード対応</td>
注意:zh-Hans 比 zh-CN 更稳妥,尤其当表格可能被港澳台用户访问时;ja 就足够,不需要写 ja-JP,除非你明确区分日本本土和海外日语变体。
- 数值、代码、符号(如
USD、2026-07-07)不需设lang,它们无自然语言发音规则 - 缩写词如
API、UI若出现在中文上下文中,建议包裹<span lang="en">API</span>,否则读屏会按中文拼音硬读 - 避免在
<th> 上乱用 <code>lang="en"只因为“看起来像英文”——如果标题实际是中文术语(如“用户ID”),就该用lang="zh-Hans":lang()CSS 在表格里容易失效的两个原因你写了
td:lang(zh-Hans) { font-family: "PingFang SC", sans-serif; }却没生效?大概率卡在这两点:-
:lang(zh-Hans)是精确字符串匹配,<td lang="zh-CN"> 不会命中它;反过来也一样。别指望一个规则通吃所有中文变体 <li>表格单元格若含内联元素(如 <code><strong></strong>),而lang又只写在<td> 上,那 <code>strong:lang(zh-Hans)会失败——因为<strong></strong>自身没lang,也不继承父级的:lang()匹配逻辑更实用的做法是用属性选择器前缀匹配:
td[lang^="zh"]覆盖zh-Hans、zh-CN、zh-Hant;或者干脆把字体规则写在td上,靠lang控制其他行为(如引号、断词)。动态渲染表格时,lang 属性必须随内容一起注入
用 JS 拼接字符串或 Vue/React 渲染表格时,别漏掉
lang——它不是装饰性属性,而是可访问性刚需。常见坑:-
innerHTML = <td>Bonjour</td>→ 缺少lang="fr",读屏仍读“帮朱瓦” - Vue 中写
<td :lang="row.lang">{{ row.text }}</td>,但row.lang是空或非法值(如"french"),会导致静默失效 - React 使用
dangerouslySetInnerHTML时,若原始 HTML 字符串里没带lang,JS 无法事后补救——必须源头生成时就带上
服务端模板(如 EJS、Twig)更可靠:直接把语言码从数据层透传到
<td lang="{{ cell.lang }}">。前端框架里建议把语言信息作为字段结构的一部分,而不是靠 guess 或 fallback。 <p>表格里最容易被忽略的是表头分组(<code><thead>)、跨列单元格(<code>colspan)和空单元格——只要里面含自然语言文本,哪怕只有一个词,就得标lang。空<td> 不用标,但 <code><td> </td>如果是占位用的,也不需要。 -
-











