css变量无法实时切换字体族,因浏览器样式计算阶段已解析完毕;应通过class切换预设字体栈或[lang="xx"]属性选择器硬编码字体链实现稳定切换,末尾必保留通用字体族。

CSS变量本身不能直接触发字体族的实时切换——浏览器在样式计算阶段就已解析完font-family: var(--font-body),后续改变量值不会重载字体或触发重排。
用 class 切换预设字体栈(最稳)
把完整字体链硬编码进 CSS 规则,靠 class 控制哪一套生效,绕过变量动态更新的限制。
-
:root里定义几套字体链:--font-sans: "Inter", -apple-system, sans-serif;、--font-serif: "Noto Serif SC", serif; - 默认 body 用:
font-family: var(--font-sans); - 写覆盖类:
.font-serif { font-family: var(--font-serif); }——注意不是“改变量”,而是整条规则替换 - JS 切换只动
document.body.className,不调style.setProperty - 别用
.font-inter这类含字体名的 class,否则换字体时 JS 和 CSS 都得同步改
用 [lang="xx"] 匹配语言并声明字体(最准)
必须显式设置 html lang="zh-CN",然后在 CSS 中为每种语言写完整 font-family 声明,var() 只是组织手段,不能省略实际值。
- 错误写法:
:root { --font-zh: "Noto Sans SC"; } html[lang="zh-CN"] { font-family: var(--font-zh), sans-serif; }—— 变量不会被覆盖,规则可能静默失效 - 正确写法:
html[lang="zh-CN"] body { font-family: "Noto Sans SC", "PingFang SC", system-ui, sans-serif; } -
system-ui必须放在自定义字体之后、sans-serif之前,否则 macOS 和 Windows 渲染不一致 - 深层文本节点容易漏匹配,要写全选择器链:
html[lang="ar-SA"] p, html[lang="ar-SA"] span
为什么 :lang() 比 [lang|="xx"] 更可靠
:lang(zh) 是语义继承匹配,[lang|="zh"] 是纯字符串前缀匹配,后者不继承、不处理缺失 lang 的嵌套元素,且无法匹配 lang="zh"(无连字符)这种合法值。
-
p:lang(ja)在父级<article lang="ja-JP"></article>下仍生效;而p[lang|="ja"]要求p自身有lang属性 - SPA 动态切语言时,必须改
document.documentElement.lang,仅改 class 或 state 无效 -
:lang(en)能匹配lang="en-US"的子元素(继承行为),不是 bug - 服务端渲染时,务必校验
lang值格式,拒绝如lang="x-hacker"这类非法输入,否则:lang(x-hacker)规则可能意外命中
真正难的不是写几行 CSS,而是确保 lang 属性从 HTML 根节点开始就存在、格式合法、且在 JS 切换时被真实修改——漏掉任一环,字体切换就静默失败。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











