lang属性必须严格遵循BCP 47标准(如zh-CN、ja-JP),写错或漏设会导致浏览器跳过中文字体链而启用西文fallback,引发标点异常、混排错乱或方块字;需在具体元素显式声明,字体链须将语言专用字体置首、sans-serif置尾,并配合font-display:swap确保回退生效。

lang 属性不写对,字体回退就失效
浏览器不是靠内容猜语言,而是严格按 lang 值触发内置的语言感知字体链。写错、漏写或用非标准格式(如 zh_CN、chinese、zh),中文就会被当成英文走西文字体 fallback 链——结果是标点撑开、引号变英文、混排时中文糊成一片,甚至直接显示方块。
必须用 BCP 47 标准写法:zh-CN(简体中文)、zh-TW(繁体中文)、ja-JP(日语)、en-US(美式英语)。iOS VoiceOver 和 Safari 对 ja 这种短格式支持不稳定,ja-JP 才稳妥。
-
html根标签的lang是唯一可靠的主语言声明,影响 SEO、屏幕阅读器、自动翻译和默认字体链 - 局部多语言内容(比如一段法语引用、
<pre lang="bash">)必须显式加lang,不能依赖继承 - 后端返回的
lang值(如ZH-CN或zh_ch)需前端转为小写+连字符,否则被忽略
:lang() 规则里 font-family 怎么排才不翻车
:lang(zh) 这类伪类能生效,前提是对应元素真有合法 lang 值。但更稳妥的做法是直接在具体选择器里写,比如 p[lang="zh-CN"] 或 blockquote[lang="fr"]。
每个语言规则的 font-family 不是堆名字,而是单向尝试链:浏览器从左到右匹配,一旦某个字体可用就停,后面全跳过。所以顺序决定一切:
立即学习“前端免费学习笔记(深入)”;
- 把该语言专用字体放最前:
"PingFang SC"(简体中文)、"Hiragino Kaku Gothic Pro"(日文)、"Apple SD Gothic Neo"(韩文) - 避免跨语言混搭,比如在
:lang(zh)里塞"Meiryo",它对中文支持弱,易导致假名宽度异常 - 末尾必须是
sans-serif或serif,不能是system-ui—— 它会绕过所有语言专用字体,直接 fallback 到系统默认拉丁字体 - 字体名含空格必须用双引号包裹:
"Noto Sans SC",写成Noto Sans SC会被拆成三个独立字体名
@font-face 中 src 顺序和 font-display: swap 是硬性前提
自定义字体要真正“可回退”,得让浏览器先试网络字体、再 fallback 到系统字体。如果 src 里把 local("PingFang SC") 放前面,macOS 上它永远只用系统字体,后面所有 url() 都不会加载。
正确写法是:
@font-face {
font-family: 'MyFont';
src: url('fonts/myfont.woff2') format('woff2'),
local("PingFang SC"),
local("Microsoft YaHei");
font-display: swap;
}
-
font-display: swap必须写在每个@font-face规则内部,写在body或其他选择器里无效 - 不加
font-display: swap,浏览器默认 FOIT(文字消失),等字体加载完才渲染——这时候根本没机会回退,因为文本压根没出现 - Safari 14.1+ 才完整支持
swap,旧版会退化为auto(即 FOIT),所以系统字体链必须足够健壮 -
font-weight和font-style必须与实际字体文件一致;woff2 文件是 normal + normal,但 CSS 写了font-weight: 700,浏览器就认为不匹配,直接跳过
富文本插入或 SPA 切换语言时容易被忽略的细节
富文本编辑器插入的 <p> 若没带 lang,即使根节点是 zh-CN,这段仍走英文 fallback 链。同理,SPA 切换语言时只改 document.documentElement.lang,已渲染的子元素完全不受影响——屏幕阅读器、拼写检查、字体引擎全按每个元素自己的 lang 值工作。
- 切换语言后,必须遍历所有带
lang的元素,同步更新它们的值(比如博客里一段<blockquote lang="ja-JP">,主语言切到英文时它不该跟着变) - 技术文档中夹
<code lang="en">useState</code>,加lang可触发 IDE 插件英文高亮,也确保浏览器用英文字体渲染变量名 - 不要给每个单词都加
lang,DOM 体积增大、可访问性树构建变慢,得不偿失;粒度控制在段落、引用、代码块级别即可 - 验证是否生效别只看 DevTools 的
font-family计算值,要展开 Computed →font-family→ “resolved value”,确认第一个生效字体是不是"Microsoft YaHei"或"PingFang SC"



















