:lang()选择器必须依赖html标签的非空合法lang属性才能生效,空值、缺失或非法代码均导致规则静默失效;需精确匹配或前缀匹配语言代码,并配合正确font-family层级顺序使用。

html 根标签没写 lang 属性,:lang() 就完全不工作
浏览器不会自动推断页面语言,html 标签必须带非空 lang 属性,否则所有 :lang() 规则都会静默失效。
常见错误写法:<html>(没属性)、<html lang="">(空值)、<html lang="zho">(非法代码)。
正确写法示例:
<html lang="zh-CN"><html lang="ja"><html lang="en">
混合内容(比如一段里夹日文)必须给具体元素加 lang:<p lang="ja">こんにちは</p>,否则 :lang(ja) 不会命中。
立即学习“前端免费学习笔记(深入)”;
:lang(zh) 和 :lang(zh-CN) 匹配逻辑不一样
:lang(zh) 是前缀匹配,能命中 lang="zh"、lang="zh-CN"、lang="zh-Hans";但 :lang(zh-CN) 只匹配精确等于 zh-CN 的值,不兼容 zh-Hans 或 zh。
Safari 对子标签解析更严格,有时 :lang(zh) 在它身上不触发 zh-Hans。稳妥做法是并列声明:
html:lang(zh), html:lang(zh-CN), html:lang(zh-TW), html:lang(zh-HK) {
font-family: "PingFang SC", "Hiragino Sans GB", sans-serif;
}
别用 [lang="zh"] 替代 —— 它只匹配字面完全相等,无法处理变体。
font-family 顺序错一位,中文字体就彻底失效
中英文字体必须分层控制:CJK 字体放最前,西文字体紧随其后,sans-serif 或 system-ui 放最后兜底。
错误写法::lang(zh) { font-family: sans-serif, "PingFang SC"; } → 英文段落先被 sans-serif 拦截,中文根本用不上 PingFang SC。
正确结构要点:
-
:lang(zh)规则里,优先放强支持简体中文的字体,如"PingFang SC"、"Microsoft YaHei" - 西文字体(如
"Inter"、"Segoe UI")必须放在 CJK 字体之后,不能放最前 -
sans-serif必须保留且放末尾,它不参与语言适配,只 fallback 缺字场景
日文、韩文同理::lang(ja) 前置 "Hiragino Kaku Gothic Pro",:lang(ko) 前置 "Malgun Gothic"。
明明写了 :lang(),但字体没变?先查 computed style
别只看页面是否“看起来像变了”,很多效果其实是全局 body 字体或系统 fallback 的巧合。
真实验证步骤:
- 打开开发者工具 → Elements 面板 → 找一个带
lang="zh"的元素(如<p lang="zh"></p>) - 右键 → “Force element state” → 勾选
:lang(zh),观察样式是否立刻变化 - 切换到 Computed 面板 → 查
font-family最终计算值,确认是否包含你写的中文字体名,而不是被更高特异性规则覆盖 - 临时加测试样式:
:lang(zh) { outline: 2px solid red; },没红框说明根本没匹配上
最容易被忽略的是 HTML 层的 lang 声明缺失,而不是 CSS 写得不够多。一旦根节点语言没标对,后面所有 :lang() 都是摆设。


















