lang属性必须写在标签上,其他位置无效;中文推荐zh-cn,多语言混排需显式标注子元素lang,js动态修改document.documentelement.lang对已加载内容基本无效。

lang属性不是装饰,它是浏览器和辅助技术读取页面语言的唯一依据;只设根标签、写错格式、忽略局部混排,都会让翻译、朗读、SEO全部失效。
lang属性必须写在html>标签上,其他位置无效
浏览器、屏幕阅读器、搜索引擎只认html元素上的lang值作为整页主语言。写在body、div或任意子元素里,对页面级语言声明完全无用——它只能影响该元素及其子节点的局部语言识别,不能替代根声明。
- 错误写法:
→ 页面被当作“无语言声明”处理,SEO降权、翻译按钮不出现、VoiceOver按系统默认语言朗读 - 正确写法:
(服务端直出最稳)或 JS 动态设置document.documentElement.lang = "zh-CN"(仅限 SPA 首次加载后补救) - 别用
<meta http-equiv="Content-Language">——HTML5 已弃用,所有现代浏览器忽略
局部多语言内容必须显式为每个元素设lang,不能靠继承
页面里夹一段英文术语、日文引用、代码注释里的西班牙语?这些内容不会自动继承html的lang值。浏览器和 NVDA/JAWS 在 DOM 解析初期就固化每个节点的语言上下文,之后改根节点毫无作用。
- 必须手动标注:
<p lang="en">API</p>、<blockquote lang="fr">Merci beaucoup</blockquote>、<pre class="brush:php;toolbar:false;" lang="en"># Initialize counter</pre> - 别给
<pre class="brush:php;toolbar:false;"></pre>写lang="bash"——这不是合法 BCP 47 语言码,应写lang="en"或lang="zh",再靠 class 控制语法高亮 - 混排段落中,英文部分需单独包裹:
<p>我们使用<span lang="en">React Router</span>实现路由</p><div class="aritcle_card flexRow artxards"> <div class="artcardd flexRow"> <a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill6712" title="Wechat HTML Publisher"><img src="https://img.php.cn/upload/skill/000/000/081/179109368394970.jpg" alt="Wechat HTML Publisher" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a> <div class="aritcle_card_info flexColumn"> <a rel="nofollow" href="/xiazai/skill6712" title="Wechat HTML Publisher" class="overflowclass">Wechat HTML Publisher</a> <p class="overflowclass">直接上传HTML富文本到微信公众号草稿箱。支持完整的HTML格式,无需Markdown转换。</p> </div> <a rel="nofollow" href="/xiazai/skill6712" title="Wechat HTML Publisher" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span> </a> </div> </div>
lang值必须符合BCP 47标准,大小写和分隔符都不能错
写错格式等于没写。浏览器静默忽略,但后果严重:语音引擎乱读、CSS :lang() 不匹配、Google 当作未标注语言。
- ✅ 正确:
zh-CN、en-US、ja-JP、pt-BR(短横线-,小写,地区码推荐带上) - ❌ 错误:
zh_CN(下划线)、Chinese(非 ISO 码)、zh-ch(大小写混用)、zh-hans-cn(三段式不被 IANA 收录,Chrome 降级为zh) -
:lang(zh-CN)不匹配lang="zh-Hans",也不匹配lang="zh";如需宽泛匹配,得写多个伪类::lang(zh-CN), :lang(zh-Hans), :lang(zh)
SPA切换语言时,必须同步更新document.documentElement.lang和所有含lang的元素
只调用document.documentElement.lang = "en-US",页面文本看着变了,但屏幕阅读器仍在用中文引擎读英文单词,“行”仍被读成háng——因为每个p、span、blockquote的lang属性还是旧值。
- 切换前先缓存滚动位置:
const scrollY = window.scrollY - 遍历并更新所有已设
lang的元素:document.querySelectorAll("[lang]").forEach(el => el.lang = newLang)(注意:保留明确要维持原语言的节点,如日文引文) - 更新完立即恢复滚动:
window.scrollTo(0, scrollY),否则页面跳顶 - 强制屏幕阅读器重读根节点:
document.title = document.title(空赋值触发重载)
最容易被忽略的是:局部混排内容的lang属性一旦写死,就和主语言切换解耦——你切到英文,那段lang="ja"的日文引用依然得是日语,不能跟着变。这需要在语言包和标记设计阶段就明确哪些内容“可切换”,哪些“固定语种”。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










