lang属性必须在首屏html中写死,js后期修改无效;浏览器和屏幕阅读器仅解析初始html的值,后续赋值不触发重读、翻译或seo更新,ssr需服务端注入,spa应整页刷新或重写outerhtml。

lang属性必须在首屏HTML中写死,JS后期修改基本无效
浏览器和屏幕阅读器(如NVDA、VoiceOver)只在解析初始HTML时读取document.documentElement.lang,一旦DOM树构建完成,再执行document.documentElement.lang = "en-US"不会触发重解析。翻译按钮不出现、语音引擎不切换、SEO抓取仍用旧值——这些都不是bug,是设计使然。
常见错误包括:在React/Vue组件里useEffect中改lang,或在SPA路由切换后调用document.documentElement.setAttribute("lang", ...)。这些操作对已激活的辅助技术会话几乎零影响。
- SSR框架(Next.js/Nuxt)必须在服务端模板中注入真实语言值,例如Next.js的
app/layout.tsx里用 - 静态站点(Hugo/Jekyll)应为每种语言生成独立HTML文件,
lang硬编码进模板头部 - 纯前端SPA若无SSR支持,唯一可靠方案是语言切换时整页刷新:
window.location.href = "/en/",而非局部更新
动态插入内容时,lang不能靠继承,必须显式标注
即使已正确设置,后续用JS插入的<p>API文档</p>仍会被屏幕阅读器按中文朗读——哪怕它实际是英文术语。因为lang不自动继承到动态节点,且浏览器不会回溯补全。
正确做法是在插入时直接带上属性:el.innerHTML = '<p lang="en">API</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>',或用createElement手动设:const p = document.createElement("p"); p.lang = "en"; p.textContent = "API";
- 第三方脚本(如评论框、广告SDK)生成的DOM通常不带
lang,需监听MutationObserver主动补标 - 代码块、引文、术语等语义明确的片段必须单独设
lang,例如<pre class="brush:php;toolbar:false;" lang="bash">curl -X POST</pre>比<pre class="brush:php;toolbar:false;" lang="zh-CN"></pre>更准确 - 避免给每个单词都加
lang,DOM体积膨胀会影响可访问性树构建性能
BCP 47格式错误会导致lang“形同虚设”
写错lang值不会报错,但等于没写:搜索引擎忽略、屏幕阅读器朗读错、:lang(zh)样式完全不匹配。IANA语言子标签要求小写字母+短横线,且区域码需符合ISO 3166-1 alpha-2标准。
典型非法值:zh_CN(下划线)、Chinese(非BCP 47)、zh-ch(区域码不存在)、zh-hans-cn(三段式不被推荐)。合法值仅限zh-CN、en-US、fr-FR等。
- 中文首选
zh-CN:兼容性最稳,所有主流辅助技术、SEO工具、字体fallback链都默认适配它 - 不要用
zh或zh-Hans替代zh-CN——前者粒度太粗,后者在Chrome中可能静默降级为zh - 多语言站点中,
hreflang与lang必须一致但独立维护,例如<link rel="alternate" hreflang="zh-CN" href="/zh/">对应页面
局部混排内容不标注lang,会破坏可访问性链路
一个页面里夹一段法语引文<blockquote>Je suis français.</blockquote>,若不加lang="fr",屏幕阅读器会强行用中文TTS引擎读出“热苏伊弗朗塞”,而不是法语发音。
这不是UI问题,而是可访问性合规红线。WCAG 3.1.2(语言识别)明确要求:用户代理能确定每段文本的语言,以便正确断词、发音、拼写检查。
- 外文术语、代码标识符、命令行示例都应标注,例如
<code lang="en">useState或<kbd lang="ja">Enter</kbd> - 注意
lang和dir配合:阿拉伯语需同时设lang="ar"和dir="rtl",否则文字方向可能异常 - 切换语言时,必须遍历所有已带
lang属性的元素同步更新,除非你明确想保留原语言(如一段日文引用始终该是日语)
lang="zh-CN",而是让每个动态插入、跨框架渲染、第三方脚本生成的文本节点,都带着准确的语言上下文被解析。这需要从服务端注入、客户端补标、第三方协作三个层面同时控制。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










