css变量在:lang()中不生效,因其作用域静态且var()在声明时即解析,无法响应运行时语言匹配;必须在:lang()规则内直接声明变量并使用var()引用。

直接改 :root 里的 CSS 变量不生效——:lang() 是伪类,它不会触发变量重计算,变量作用域是静态的。
为什么 font-family: var(--font-zh) 在 :lang(zh) 里不工作
很多人想这么写:
:lang(zh) { font-family: var(--font-zh); }
:lang(en) { font-family: var(--font-en); }
但浏览器会忽略——因为 var() 在声明时就解析完了,:lang() 匹配是运行时行为,变量本身不会“响应式更新”。你看到的其实是 fallback 到全局默认字体。
-
--font-zh和--font-en必须在匹配到的元素上直接声明,不能靠继承或间接引用 - 哪怕你在
:root里设了--font-zh: "PingFang SC",:lang(zh)里写font-family: var(--font-zh)也等同于没写(Chrome/Safari/Firefox 均如此) - 真正起效的是:在
:lang(zh)规则体内直接写死font-family值,或用font-family: inherit配合父级显式设置
正确做法:把变量声明落到 :lang() 规则内部
变量不是用来“存字体名”的中转站,而是用来复用值的。比如行高、字重、间距这些跨语言共用但需微调的属性。
字体本身必须直写进 :lang() 规则:
:lang(zh) {
--line-height: 1.7;
--font-main: "HarmonyOS Sans SC", "Noto Sans SC", sans-serif;
font-family: var(--font-main);
}
:lang(ja) {
--line-height: 1.65;
--font-main: "Yu Gothic", "Noto Sans JP", sans-serif;
font-family: var(--font-main);
}
:lang(en) {
--line-height: 1.5;
--font-main: system-ui, -apple-system, "Segoe UI", sans-serif;
font-family: var(--font-main);
}
- 每个
:lang()规则内都得有完整的font-family声明,var()只是辅助组织,不能替代 - 变量名如
--font-main没有特殊含义,只是方便维护;换掉名字不影响功能 - 别在
:root里定义--font-main后指望:lang()自动覆盖——它不会覆盖,只会被忽略
动态切换语言时,如何避免字体闪动(FOUT)
用户点“切换为日语”,document.documentElement.lang = 'ja',浏览器重新匹配 :lang(ja),触发新字体加载。如果没预处理,就会看到从英文系统字体 → 日文字体的跳变。
- 提前用
<link rel="preload" as="font">加载所有目标语种的@font-face资源,包括crossorigin属性 -
@font-face的font-family名必须唯一且与:lang()中引用的一致,例如都叫"LangJP",否则浏览器可能复用缓存但渲染错字形 - 不要依赖 JS 改完
lang立刻读getComputedStyle——CSSOM 更新有延迟,可加requestAnimationFrame延迟一帧再操作 - Safari 对动态插入的
lang属性支持更弱,建议初始 HTML 就带,切换时只改值,不删重建
最易被忽略的兼容性坑:Safari + 动态 lang + :lang()
Safari 要求 lang 属性必须在 DOM 初始化时就存在,或至少在样式计算前已挂载。JS 动态设置后,:lang(zh) 可能完全不触发,尤其在 innerHTML 替换内容后。
- 解决方案:给根节点设默认
lang,所有子元素靠继承;局部覆盖时用<p lang="ja"></p>显式声明,别全靠 JS 注入 - 验证是否生效:打开 DevTools,在 Elements 面板检查目标元素是否真有
lang属性,且值是标准 BCP 47 格式(如zh-CN,不是chinese) - 别用
[lang="zh"]替代:lang(zh)——前者不继承,后者支持zh-TW、zh-HK等子语言自动匹配
事情说清了就结束。最关键的不是变量怎么写,而是理解 CSS 变量和伪类的生命周期根本不重叠——一个编译期静态,一个运行时动态。硬凑在一起,只会白忙活。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











