必须用 lang="ja",因为它是 BCP 47 标准中日语的合法主标签;lang="ja-JP" 冗余,lang="japanese" 或 lang="jp" 非法会被忽略,且 lang 必须直接写在承载日语文本的元素上才能确保屏幕阅读器、翻译和 CSS 正确识别。

lang="ja" 是标记日语内容的正确写法,不是 lang="ja-JP"、lang="japanese" 或 lang="jp"。它必须直接写在承载日语文本的元素上,否则屏幕阅读器、翻译引擎和 CSS 选择器都可能失效。
为什么必须用 lang="ja" 而不是其他变体
BCP 47 标准中,日语的主语言子标签是 ja(ISO 639-1),不带区域后缀已足够准确。浏览器和读屏软件(如 VoiceOver、NVDA)对 ja 的支持最稳定:
-
lang="ja-JP"不报错但冗余——除非你明确区分日本本土与海外日语(如巴西日裔社区用语),否则无实际收益 -
lang="japanese"或lang="jp"是非法值,会被静默忽略,:lang(ja)样式不生效,拼写检查不启动 -
lang="ja-Hira"等自定义变体不存在于标准中,Chrome/Firefox/Safari 全部无视
lang="ja" 必须写在具体文本容器上,不能靠父级继承
表格、段落、代码块里的日语,必须各自声明,<table lang="en"> 或 <div lang="ja"> 这类写法无效:
-
<td>東京</td>→ 读作中文音调,“东”“京”二字被硬切 -
<td lang="ja">東京</td>✅ 触发日语 TTS 引擎,正确朗读长音和促音 -
<p>ReactのuseEffectフックは...</p>→ 混排内容全按中文规则断词 -
<p lang="ja">ReactのuseEffectフックは...</p>✅ 假名+汉字混合结构被正确识别为日语语法单元
混排场景下怎么处理「日语里夹英文术语」
一个 <td> 或 <p> 里既有日语又有英文技术词(如 useState、API),不能整个元素设 lang="ja" 然后指望浏览器智能切分:
立即学习“前端免费学习笔记(深入)”;
- 英文术语应包裹在语义化元素中并单独声明:
<code lang="en">useState</code>、<span lang="en">API</span> - 避免用
<div lang="en">——<div>无语言语义,读屏软件可能跳过或降级处理 - 不要写
<span lang="ja">useState</span>—— 英文单词被日语引擎强行注音,变成 /yoo-z-steyt/ 类似发音 - CSS 中可用
:lang(ja) { font-family: "Hiragino Kaku Gothic Pro"; },但需配合[lang="en"] { font-family: system-ui; }防止英文术语被日文字体覆盖
SPA 动态渲染日语内容时容易漏掉的关键点
React/Vue 渲染表格或列表时,仅在初始 HTML 里写对 lang 不够;JS 注入的新 <td> 若没同步加 lang="ja",语音引擎不会重载:
- 服务端渲染(SSR)阶段就要把
lang写进字符串模板,例如:`<td lang="ja">${item.jaText}</td>` - 客户端用
innerHTML拼接时,必须显式插入lang="ja"属性,不能依赖后续 JS 补充 -
document.documentElement.lang = "ja"只影响根语言信号,不会让已挂载的<td>自动获得日语行为 - 测试时用 VoiceOver + Safari 打开 DevTools,右键元素 → “检查访问性”,确认
language字段显示ja
真正容易被忽略的是:日语假名(如「こんにちは」)一旦被错误标记为 lang="en",VoiceOver 会按英语音节切分,把「は」读成 /hɑː/ 而非 /wa/;这种发音错误无法靠样式或字体修正,只能靠每个文本节点的 lang 声明来根治。



















