应使用 HTML 的 lang 属性精准标注专有名词语言边界,并在必要时配合 aria-label 提供口语化发音提示,避免依赖 translate="no" 或 JS 拼音注释。

用 lang 属性标注专有名词语言边界
屏幕阅读器默认按页面整体 lang 属性决定发音规则,遇到中文页面里的英文人名、地名或技术术语(如 “React”、“Tokyo”、“SQL”)时,常读错音或强行用中文音译。解决办法不是靠 JS 拼音注释,而是用 HTML 原生的 lang 属性精准切分语言上下文。
- 在专有名词外层包裹一个
<span lang="en">React</span>,屏幕阅读器就会切换英语发音引擎 - 对混合语境更稳妥:比如 “GitHub 仓库”,写成
<span>GitHub</span> 仓库不够,应为<span lang="en">GitHub</span> 仓库 - 避免嵌套错误:不要在已设
lang="zh"的容器里再套lang="zh"—— 无意义且可能干扰继承链 -
lang值必须是合法 BCP 47 标签,如en-US、ja、ko-KR;zh比zh-CN更通用,但若明确需普通话发音,优先用zh-CN
配合 aria-label 覆盖不可靠的自动朗读
有些专有名词本身拼写不反映发音(如 “MySQL” 读作 /maɪˈɛskjuːɛl/ 而非 “my sequel”),或缩写存在多义(如 “API” 在不同场景读作 /ˈeɪpiːaɪ/ 或 /ˌeɪ.piːˈaɪ/)。此时 lang 不够,需用 aria-label 显式提供发音提示。
- 仅用于真正需要干预的场景:
<span aria-label="my sequel">MySQL</span> - 别滥用:
aria-label会完全覆盖视觉文本,若用户能看清原文又想听准发音,这是合理取舍;但若只是普通英文单词(如 “button”),不必加 - 值应为自然口语化发音,不用音标(屏幕阅读器不解析 IPA),例如写
"kay-ess-ell"而非"/kɛsɛl/" - 注意与
title冲突:二者同时存在时,多数屏幕阅读器优先读aria-label,title形同虚设,直接删掉
警惕 translate="no" 的误用场景
translate="no" 告诉浏览器“不要翻译这段文本”,但它**不控制发音**,只影响机器翻译插件或内置翻译功能。很多开发者以为加了它就能让屏幕阅读器正确读专有名词,结果发现 VoiceOver 或 NVDA 还是乱读 —— 因为发音和翻译是两套机制。
- 适用场景:防止 Google Translate 把 “iOS” 翻成 “苹果操作系统” 或把 “Vue” 翻成 “视图”
- 无效场景:不能解决 “JPEG” 被读成 “j-peg” 还是 “jay-peg” 的问题;也不能让 JAWS 把 “C++” 正确读作 “see plus plus”
- 替代方案:对这类符号/特殊拼写,仍应回到
aria-label或拆解为可读字符串(如<span aria-label="see plus plus">C++</span>)
动态内容中如何保持语言属性生效
通过 JavaScript 插入含专有名词的文本时,容易丢失 lang 或 aria-label。DOM 更新后,屏幕阅读器不会自动重新探测语言边界,必须手动补全语义。
立即学习“前端免费学习笔记(深入)”;
- 插入节点前,确保新元素自带
lang:el.innerHTML = '<span lang="en">GraphQL</span>'; - 用
dataset存发音提示再注入:const span = document.createElement('span'); span.dataset.pronounce = 'graph q l'; span.textContent = 'GraphQL';,然后在 JS 中根据 dataset 动态设aria-label - 避免 innerHTML 直接拼接:易遗漏属性,改用
createElement+setAttribute组合更可控 - 关键点:每次 DOM 变更后,检查辅助技术是否能聚焦并朗读新内容——仅靠自动化工具扫不出发音问题,必须手动用 VoiceOver/NVDA 验证



















