推荐用 CSS 变量配合 class 切换字体:在 :root 定义 --font-serif 和 --font-sans,body 设 font-family: var(--font-sans),通过 .font-serif { --font-sans: var(--font-serif); } 覆盖变量,切换时仅修改 body.className,并用 localStorage 持久化偏好,fallback 链需按系统习惯书写并以通用族名结尾。

怎么用 CSS 变量 + class 切换字体
直接改 body 或根元素的 font-family 会触发全页重排,体验卡顿;更稳的做法是定义几套预设字体族,用 class 控制切换,配合 CSS 变量统一管理。
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 在
:root里定义变量,比如--font-serif: "Noto Serif SC", serif;和--font-sans: "Inter", -apple-system, sans-serif; - 给
body设置font-family: var(--font-sans);,再写两个 class:.font-serif { --font-sans: var(--font-serif); }(注意这里是在覆盖变量值) - 切换时只改
document.body.className = 'font-serif',不操作 style 或 innerHTML - 避免在 class 名里硬编码字体名(如
.font-inter),否则换字体要同步改 JS 和 CSS,耦合高
localStorage 记住用户上次选的字体
用户切完字体关掉页面又打开,得还原——不能靠 cookie 或服务端存,纯前端就靠 localStorage。
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 切换字体时立刻执行
localStorage.setItem('ui-font', 'serif') - 页面加载后读取:
const saved = localStorage.getItem('ui-font');,存在则加对应 class 到body - 别用
sessionStorage,它关标签页就丢,不符合“记住偏好”的预期 - 加个兜底:如果
localStorage读失败(比如隐私模式下 Safari 会抛错),直接用默认字体,别让页面白屏或报错中断
为什么不能直接用 document.fonts.load() 做字体切换校验
document.fonts.load() 是用来预加载字体的,不是用来判断当前生效字体的。它返回 Promise,但成功只代表字体文件已加载,不代表 font-family 已应用到元素上,更不反映系统是否真有该字体。
常见错误现象:
- 调用
document.fonts.load('12px "Missing Font"')返回 resolved,但实际渲染还是 fallback 字体 - 误以为能靠它检测用户系统里有没有 “霞鹜文楷”,结果永远返回成功(因为浏览器只管下载,不管安装)
- 在字体切换后立即测
getComputedStyle(el).fontFamily,拿到的还是旧值——CSS 变更还没 layout 完成
真正需要校验时,应该用 window.matchMedia 配合 font-feature-settings 测试(极少数场景),或者干脆放弃校验,靠合理 fallback 链保底。
中文字体 fallback 链怎么写才不踩坑
中文网页最常崩在 Windows 上显示成方块或宋体,根源是 fallback 链没按系统习惯写,或者用了不存在的字体名。
实操建议:
立即学习“前端免费学习笔记(深入)”;
- Windows 用户优先用
"Microsoft YaHei", "SimSun", sans-serif;Mac 用"PingFang SC", "Hiragino Sans GB";Linux 少见但可加"Noto Sans CJK SC" - 别写
"KaiTi"或"FangSong"单独出现——这些字体在 Win10+ 默认不启用,且无英文字符支持,容易断链 - 用引号包裹含空格的字体名,比如
"Helvetica Neue",但系统内置字体如system-ui、sans-serif不加引号 - 最后必须带通用族名(
sans-serif/serif),否则某些老旧 Android 或 KaiOS 设备可能渲染异常
字体切换不是换皮肤那么简单,关键在 fallback 链是否经得起不同系统、不同语言环境、不同安全策略的考验。变量控制 + class 切换 + localStorage 持久化,这三步缺一不可,而每一步的细节都可能让效果打折扣。



















