直接修改CSS变量--font-body的值不会触发字体实时切换,因浏览器在样式计算阶段已解析完毕;应通过class切换预设字体栈或[lang]属性选择器配合硬编码字体链实现稳定切换,末尾必须保留通用字体族。

直接改 --font-body 变量值不会让字体立刻切换——浏览器在样式计算阶段就解析完 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-sans: var(--font-serif); }—— 注意这里不是“切换变量”,而是用新值覆盖旧变量作用域 - JS 切换只动
document.body.className,不碰style.setProperty - 别用
.font-inter这类含字体名的 class,否则换字体时 JS 和 CSS 都得同步改
用 [lang] 属性选择器做多语言切换(最准)
:lang(zh) 不可靠,[lang="zh-CN"] 才是稳定方案,它匹配显式属性且继承确定:
- 确保 HTML 根节点有
<html lang="zh-CN">,语言切换时只改document.documentElement.lang - CSS 必须写完整选择器链:
html[lang="zh-CN"] body, html[lang="zh-CN"] p,避免漏掉深层文本节点 - 每条规则里写死字体栈:
font-family: "Noto Sans SC", "PingFang SC", system-ui, sans-serif;——var(--font-zh)在这里只是组织手段,不能省略实际声明 -
system-ui必须放在自定义字体之后、sans-serif之前,否则 macOS 和 Windows 渲染不一致
为什么 document.fonts.load() 不能校验字体是否生效
它只管下载,不管渲染,返回成功 ≠ 字体已应用到元素上:
立即学习“前端免费学习笔记(深入)”;
-
document.fonts.load('12px "Missing Font"')可能返回 resolved,但页面仍 fallback 到系统字体 - 调用后立刻查
getComputedStyle(el).fontFamily拿到的还是旧值 —— CSS 更新尚未 layout 完成 - 真正保底靠的是字体栈顺序:从左到右匹配,缺失就跳下一个,末尾必须带
sans-serif等通用族名 - 需要预加载时用
<link rel="preload" as="font" crossorigin>,而不是靠load()做开关
字体名本身不适合存进变量再取出来,变量真正该管的是行高、字重、字间距这些跨语言共用但需微调的值;而字体栈必须直写、硬编码、带通用族名结尾——这是浏览器解析规则决定的,绕不开。









