lang属性值必须严格匹配bcp 47格式,如zh-cn、en-us;用下划线(zh_cn)、非标准码(chinese)、宽泛码(zh)或含空格均导致静默失效,影响字体回退、屏幕阅读器朗读、自动翻译及:lang()样式匹配。

lang属性值必须严格匹配BCP 47格式
浏览器和辅助技术只认标准格式,写错就等于没写——不报错、不警告,静默失效。最常见错误是用下划线代替短横线,比如zh_CN或en_us,实际应为zh-CN、en-US。大小写也敏感:ZH-cn在部分iOS VoiceOver版本中无法匹配中文TTS引擎;zh-hans合法,但zh-HANS可能被旧工具拒绝。
- ✅ 正确示例:
zh-CN、en-GB、ja-JP、fr-FR - ❌ 典型错误:
zh_ch(下划线)、Chinese(非BCP 47)、zh(太宽泛,部分场景降级为und)、zh-Hans-CN(三段式,IANA未收录) - ⚠️ 注意空格:
zh-CN末尾多一个空格,也会被当非法值忽略
别把lang当“语法高亮开关”乱填
lang不是用来告诉编辑器怎么高亮的,而是告诉浏览器和读屏软件“这段文本属于哪种语言”。填lang="bash"或lang="json"是无效的——bash不是语言标签,JSON也不是。这类写法不会报错,但会导致屏幕阅读器误读、:lang()选择器不匹配、翻译模型选型错误。
- 代码块中的英文注释、命令、变量名,应标注其自然语言,如
<pre class="brush:php;toolbar:false;" lang="en">curl -X POST</pre> -
<code lang="en">useState可触发IDE英文拼写检查与语音朗读 - 若内容纯属技术符号(如
<code>const [a, b] = c;),且无自然语言成分,可留空lang,不强加
动态页面中lang更新后为何CSS和语音仍不生效
关键点在于:辅助技术在HTML解析初期就读取document.documentElement.lang,JS后期修改对已激活的朗读会话基本无效。即使你执行了document.documentElement.lang = "ja-JP",VoiceOver可能还在用旧语种引擎读已挂载的<p></p>元素。
- SSR优先:Next.js在
app/layout.tsx里用,PHP模板用 - SPA强制重读:除改
lang外,还需触发document.title = document.title(空赋值)来通知读屏软件重读根节点 - 局部内容不能靠继承:AJAX返回的JSON文案、Vue/React组件内写死的
"Loading...",即使html上lang再准,也会被当成中文渲染——必须同步替换文案语言
如何验证lang是否真正起作用
不要只看页面显示是否正常。真正有效的验证要落到三个链路上:语音朗读、自动翻译菜单、CSS伪类匹配。任一环节失效,说明lang没设对或没设到位。
- 打开Chrome,右键检查元素,确认
标签上只有且仅有lang="zh-CN"(无重复、无空格、无多余属性) - 用NVDA或VoiceOver朗读一段含英文术语的句子,听是否按英语发音规则读
API而非“阿皮” - 在开发者工具控制台运行
getComputedStyle(document.documentElement).getPropertyValue('font-family'),切换不同lang值观察是否触发对应字体链 - CSS中写
q:lang(fr) { quotes: "«" "»" "‹" "›"; },插入<q lang="fr">Merci</q>,看引号是否正确渲染
zh-CN怎么写,而是确保每个动态插入的文本节点、每段第三方脚本生成的内容、每个服务端返回的JSON字段,都带着准确的语言上下文被解析——这需要从模板层、API设计、组件封装多个环节协同控制。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











