必须在<html>标签上写lang属性,这是启动多语言支持的硬性前提;浏览器仅首次解析时读取该值,JS修改无效,且局部lang需显式标注外文内容。

必须在 <html> 标签上写 lang,否则浏览器、屏幕阅读器和搜索引擎基本不认——这不是可选项,是启动多语言支持的硬性前提。
根元素 lang 属性为什么非写不可
浏览器只在首次解析 HTML 时读取 <html lang="zh-CN">,之后任何 JS 修改(比如 document.documentElement.lang = "en-US")都不会触发语音引擎重载、翻译按钮刷新或 CSS :lang() 重新匹配。
-
<body lang="zh-CN">或<div lang="zh-CN">:完全无效,不被视作文档主语言 -
<meta http-equiv="Content-Language" content="zh-CN">:HTML5 已弃用,Chrome/Firefox/Safari 全部忽略 - 值必须符合 BCP 47:优先用
zh-CN(非zh_Hans、zh、chinese),en-US比en更稳,fr-FR比fr更利于断词和拼写检查
局部多语言内容怎么标才真正起作用
根 lang 定基调,但混排内容(如英文术语、日文引文、代码注释)必须显式加 lang,否则屏幕阅读器仍按中文规则硬读,比如把 API 读成“阿皮”,把 useState 当拼音念。
- 单个外文词:
<code lang="en">useState</code>—— IDE 高亮、语音朗读都依赖这个 - 整段非母语:
<blockquote lang="fr">Je suis français.</blockquote>,比<p lang="fr">更具语义 - 代码块上下文:
<pre lang="bash">curl -X POST</pre>,虽然bash不是标准语言码,但主流高亮工具和 Chrome 都识别它为 shell 上下文 - 避免滥用:
<span lang="en">包裹一个单词可以,但别用<div lang="en">套整个英文章节——语义不清,还可能干扰父级:lang(zh)的 CSS 匹配
动态页面里 lang 怎么更新才不翻车
SPA 切换语言时,只改 React/Vue 的 state 或 class 名,不碰 DOM 的 lang,等于没切——屏幕阅读器卡在旧语种,标点间距错乱,自动翻译提示也不出现。
立即学习“前端免费学习笔记(深入)”;
- 服务端渲染(SSR):根据请求头
Accept-Language直接输出<html lang="ja-JP">,首屏即生效 - 客户端 SPA:语言切换后立刻执行
document.documentElement.lang = "ja-JP",再遍历所有含语言信息的节点(如<code lang="en">)批量更新其lang属性 - 静态多语言站:每个语言版本单独一份 HTML 文件,
<html lang="zh-CN">硬编码,杜绝 JS 注入延迟导致的闪动或误读
lang 和 CSS :lang()、hreflang 容易搞混的点
lang 是内容语言声明,hreflang 是链接关系声明,两者用途完全不同,不能互相替代。
-
:lang(zh-CN)匹配的是元素自身或继承来的lang值,不是页面根节点;所以<section lang="en"><p>Hello</p></section>中的<p>会匹配:lang(en),哪怕根是zh-CN -
hreflang只出现在<link rel="alternate" hreflang="en" href="/en/">这类标签里,用于告诉搜索引擎“这个链接指向英文版”,用户点进去后,页面是否正确渲染仍只取决于它自己的<html lang="en"> -
translate="no"可配合lang使用:比如<span lang="en" translate="no">React</span>,既声明它是英文词,又禁止浏览器自动翻译它
最常被跳过的动作,是给局部外文内容补 lang。很多人以为写了 <html lang="zh-CN"> 就万事大吉,结果技术文档里满屏的 useState、props、npm install 全被 VoiceOver 当中文读,连破折号和英文标点的停顿都错乱——这根本不是辅助功能没开,是语言信号压根没发出去。



















