lang属性必须写在标签上且符合bcp 47标准(如zh-cn),否则屏幕阅读器无法正确识别语言,导致“javascript”被读成“加瓦脚本”等语音错乱;局部多语言内容须显式标注lang,不可依赖继承。

lang 属性不写对,屏幕阅读器就可能把“JavaScript”读成“加瓦脚本”,甚至整段英文被按中文语调顿读——这不是体验差,是内容失效。
lang 必须写在 html 标签上,否则辅助技术根本不管
浏览器和 NVDA、VoiceOver 等屏幕阅读器只认 document.documentElement.lang 作为整页语言基准。只给 <div> 或 <code><p></p> 加 lang,对语音引擎选型、字体 fallback、拼写检查默认行为几乎没影响。
- 常见错误:SPA 切换语言时只改
document.body.lang或某个容器的lang,结果 VoiceOver 还在用中文语调读英文标点 - 实操必须做:服务端渲染页,根据
Accept-Language头输出;SPA 在语言切换钩子中执行document.documentElement.lang = "ja-JP" - 别信“JS 注入就行”:iOS VoiceOver 某些版本会因
lang="ja"非标准而降级为英语发音,lang="ja-JP"才稳妥
局部多语言内容必须显式声明 lang,不能靠继承
浏览器不会自动识别「这段是法语引文」「这行是 Bash 命令」——它只看你明写的 lang 值。漏写,整段就被当成根语言处理,后果是语音停顿错、假名被中文字体渲染、拼写检查完全失效。
- 正确写法:
<blockquote lang="fr">Je suis français.</blockquote>、<pre class="brush:php;toolbar:false;" lang="bash">curl -X POST</pre>(lang="bash"虽非 BCP 47 标准码,但被主流高亮工具和 AT 识别为代码上下文) - 错误写法:
<p>The quick brown fox</p><div class="aritcle_card flexRow artxards"> <div class="artcardd flexRow"> <a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill4293" title="Doc To HTML"><img src="https://img.php.cn/upload/skill/000/000/081/178998486916110.jpg" alt="Doc To HTML" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a> <div class="aritcle_card_info flexColumn"> <a rel="nofollow" href="/xiazai/skill4293" title="Doc To HTML" class="overflowclass">Doc To HTML</a> <p class="overflowclass">使用 MinerU 文档处理引擎将 Word 文档(.doc、.docx)转换为保留结构和格式的干净 HTML。</p> </div> <a rel="nofollow" href="/xiazai/skill4293" title="Doc To HTML" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span> </a> </div> </div>(无lang),或<p lang="en"><span>HTML</span></p>(<span></span>内容仍按英文读,但若它是缩写,需额外加aria-label="Hypertext Markup Language") - 嵌套要闭合:
<section lang="zh-CN"><blockquote lang="de">Guten Tag</blockquote></section>,不能只开不关
lang 值必须符合 BCP 47,zh 和 zh_CN 都是错的
lang="zh" 不是合法 IETF 标签,AT 兼容性极差;zh_CN 下划线格式被所有浏览器忽略。错写等于没写,分词、声调、标点停顿全乱。
- 简体中文必须用
lang="zh-Hans"或lang="zh-CN"(后者更通用) - 繁体中文区分地区:
lang="zh-TW"(台湾)、lang="zh-HK"(香港) - 后端返回
zh_ch或ZH-CN?前端必须标准化为小写+连字符,否则被浏览器静默丢弃 - 别混用
hreflang:它只管链接跳转,不影响当前页朗读逻辑
容易被忽略的边界场景:placeholder、SVG title、动态弹窗
只要文本出现在 DOM 中且未被 aria-hidden="true" 或 display: none 掩盖,屏幕阅读器就会捕获并按当前元素的 lang 朗读——哪怕它只是个 placeholder。
-
<input placeholder="搜索" lang="zh-CN">,父容器若为lang="en",会被读成英文发音 -
<svg><:title>编辑</svg>必须加lang="zh-CN",否则照样读错 - JS 动态插入提示语时,不能只改
innerText,得同步设置父元素lang或用aria-label覆盖 - 最麻烦的不是写错,而是写了但没测:NVDA 和 VoiceOver 对嵌套
lang的解析深度不一致,得真机实测
真正卡住多语言可访问性的,往往不是技术难度,而是每个 lang 值是否在 DOM 初始渲染时就准确、是否覆盖了所有文本节点、是否经受过真实 AT 测试——漏掉任意一个,用户听到的就是错音、乱序、不可理解的语音流。










