应使用 :root 定义语系字体变量(如 --font-zh、--font-ja),配合 [lang] 属性选择器切换语言,避免硬编码字体或 class 控制;简繁体复用 --font-zh,通过 [lang="zh-Hant"] 覆盖;注意 unicode-range 预加载、font-display: swap 及行高一致性。

怎么用 :root 变量统一管理中日韩字体族
直接在每个选择器里写 font-family: "Noto Sans SC", "Hiragino Kaku Gothic Pro", "Malgun Gothic", sans-serif 是最常见也最危险的做法——它把语言逻辑和样式耦合死了,改一个字体会牵连所有地方。真正可控的方式是在 :root 里按语系定义变量,比如:
:root {
--font-zh: "Noto Sans SC", "PingFang SC", system-ui, sans-serif;
--font-ja: "Noto Sans JP", "Hiragino Kaku Gothic Pro", system-ui, sans-serif;
--font-ko: "Noto Sans KR", "Malgun Gothic", system-ui, sans-serif;
--font-en: "Inter", -apple-system, sans-serif;
}
然后所有文字容器统一用 font-family: var(--font-zh),切换语言时只改一个变量值,不用动结构或重写选择器。
- 别把字体名硬编码进 class 名(如
.font-jp),否则 JS 和 CSS 要同步改,漏一个就错位 -
system-ui必须放在自定义字体之后、通用族名(sans-serif)之前,否则 macOS 和 Windows 渲染行为不一致 - 中文简体/繁体不要靠同一套变量区分——它们属于同一语系但字形不同,应由
[lang="zh-Hans"]/[lang="zh-Hant"]层级控制
为什么 [lang] 属性选择器比 class 切换更可靠
用 document.body.className = 'lang-ja' 再写 .lang-ja .title 看似简单,但实际会漏掉第三方组件、服务端渲染内容、或者 shadow DOM 里的文本。而标准的 [lang="ja"] 是浏览器原生支持的继承机制,只要 HTML 根元素写了 ,所有后代元素自动匹配,无需额外 JS 干预。
- 确保
lang值符合 BCP 47 标准:用zh-CN不用zh-ch,用ja-JP不用jp - 配合
@font-face的unicode-range能精准加载对应字集,避免把日文字体全量下载给中文用户 - 如果用 i18n 库(如 Vue I18n),记得在初始化时同步设置
document.documentElement.lang,不然 CSS 选择器不生效
document.documentElement.style.setProperty() 切换字体变量的坑
很多人以为改完 --font-zh 变量,页面立刻重排,其实不是。CSS 变量更新是异步的,且不会触发字体回流校验。常见问题包括:
- 切换后立即调用
getComputedStyle(el).fontFamily拿到的还是旧值——得等requestAnimationFrame后再读 - 如果新字体还没加载完(比如 WOFF2 文件较大),会短暂 fallback 到系统字体,造成 FOUT;建议提前用
document.fonts.load()预加载,但只用于加载,别用来判断是否“可用” - 别在每次语言切换时都重新
@import字体 CSS,会导致重复请求;应把所有语言字体都提前声明在主样式表中
稳妥做法是:语言切换 → 更新 lang 属性 → 更新 CSS 变量 → 触发一次 document.fonts.load()(仅限关键字体)→ 等待 font-display: swap 自动接管渲染。
简体/繁体切换要不要单独搞一套字体变量
不需要。简繁本质是同一语系下的字形变体,不是独立语言,强行拆成两套变量会增加维护成本。正确做法是复用 --font-zh,再通过 [lang="zh-Hant"] 覆盖部分规则:
[lang="zh-Hant"] {
--font-zh: "Noto Sans TC", "PingFang HK", system-ui, sans-serif;
}
这样既保持变量统一,又保留字形适配能力。注意两点:
- 繁体字体包必须显式声明
@font-face并指定unicode-range: U+4E00-9FFF, U+3400-4DBF, U+20000-2A6DF等范围,否则浏览器可能加载失败 - Safari 在无痕模式下可能拒绝
localStorage,但lang属性是 HTML 原生属性,不受影响,所以它是唯一能跨隐私模式稳定工作的切换依据
最易被忽略的是:字体切换后,行高、字间距、甚至按钮宽度都可能变化,尤其是日文和韩文混排时。别只盯着 font-family,记得用 font-size-adjust 或统一 line-height 锚定视觉节奏。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











