:lang() 不自动切换字体,仅匹配 HTML 中显式设置的合法 lang 属性;必须手动设对根节点 lang 值(如 lang="zh-CN"),且字体声明需按“CJK字体→西文字体→sans-serif”顺序书写,并配合 JS 动态设置 lang 才能实现系统语言适配。

:lang() 本身不会“自动”切换字体——它只匹配已存在的 lang 属性,不读取系统语言、不监听变化、不推断内容。真正起作用的是你写的 font-family 声明,但前提是 HTML 根节点的 lang 属性必须手动设对,否则整套规则形同虚设。
HTML 的 lang 属性没写对,:lang() 就完全不工作
浏览器只认显式、非空、符合 BCP 47 的 lang 值,比如 <html lang="zh-CN"> 或 <html lang="ja">。以下全是无效写法:
-
<html>(压根没写) -
<html lang="">(空值) -
<html lang="ch">或<html lang="zho">(非法标签) -
<html xml:lang="zh-CN">(xml:lang在 HTML5 中不触发:lang()) -
<html lang="zh_CN">(下划线格式不被识别)
大小写不敏感(zh-cn 和 zh-CN 都行),但结构必须合规。如果页面始终是 <html lang="en">,那 :lang(zh) 永远不会生效,哪怕用户系统语言是简体中文。
:lang(zh) 和 :lang(zh-CN) 匹配逻辑不同,别混用
:lang(zh) 是前缀匹配:能命中 lang="zh"、lang="zh-CN"、lang="zh-Hans" 等;而 :lang(zh-CN) 只精确匹配 lang="zh-CN"。Safari 对子标签解析更严格,有时 :lang(zh) 不触发,但 :lang(zh-CN) 稳定生效。
立即学习“前端免费学习笔记(深入)”;
稳妥做法是并列写全:
:lang(zh), :lang(zh-CN), :lang(zh-TW), :lang(zh-HK), :lang(zh-Hans) {<br> font-family: "PingFang SC", "SF Pro SC", sans-serif;<br>}
别写 :lang("zh")(引号多余)或 :lang(zh-hans-cn)(不符合 BCP 47,多数浏览器忽略)。
字体声明顺序错了,中英文都会翻车
直接写 font-family: "Noto Sans CJK SC", sans-serif 是典型错误:西文字母会被强制套用中文字体,导致字重发虚、标点错位;更糟的是,若用户系统没装该字体,sans-serif 会回退到 Helvetica(macOS)或 Arial(Windows),而这俩对日文、韩文支持极差,结果就是方块。
正确顺序必须满足三点:
- 中日韩专用字体放最前(如中文用
"PingFang SC",日文用"Hiragino Kaku Gothic Pro") - 西文字体(如
"Inter"、"Segoe UI")必须放在 CJK 字体之后 -
sans-serif或system-ui必须放在最后兜底,绝不能放最前
混合内容(如 <p>Hello世界</p>)需在内联元素上加 lang:<span lang="zh">世界</span>,否则 :lang(zh) 不会命中。
想“自动切换”,必须用 JS 动态设置 document.documentElement.lang
:lang() 是静态匹配器,不会响应系统语言变化。要实现“根据系统语言切换”,得靠 JS:
const userLang = navigator.language || navigator.userLanguage;<br>// 提取主语言码,如 zh-HK → zh<br>document.documentElement.lang = userLang.split('-')[0] || 'en';
注意:
- 必须在
DOMContentLoaded后执行,否则可能被后续脚本覆盖 - 别只改
<body lang="zh">——:lang()行为严重依赖<html>上的lang - 改完后 CSS 不会立刻重算,可加
document.body.offsetHeight强制触发重排
最易被忽略的点是:字体链里西文字体位置不对,或者没给混合文本的内联元素单独加 lang。这两处一错,哪怕 lang 属性设对了,效果也出不来。


















