link标签不能加载系统字体,它仅支持stylesheet、icon等预定义资源类型,无法声明或注入本地字体文件;系统字体需直接在font-family中按优先级声明,由浏览器自动匹配系统已安装字体。

link标签本身不能加载系统字体
<link> 标签只支持预定义的外部资源类型,比如 stylesheet、icon、prefetch 等。它**没有机制去声明或注入本地系统字体**——浏览器不会因为你在 <link rel="font" ...> 里写个路径就去读取用户电脑上的 C:/Windows/Fonts/msyh.ttc。
常见误解是把 <link rel="preload" as="font"> 当成“加载系统字体”,其实它只是提前获取一个你明确指定的字体文件(比如你自己托管的 fonts/inter-var-latin.woff2),和系统字体无关。
想用系统字体,直接写 font-family 就行
系统字体不需要加载,只需要在 CSS 的 font-family 中按优先级列出即可。浏览器会按顺序查找用户系统中是否存在该字体:
- Windows 常见:
"Segoe UI"、"Microsoft YaHei"、"Tahoma" - macOS 常见:
"San Francisco"(系统名是.SFNSDisplay,但应写"-apple-system")、"Helvetica Neue" - Linux 常见:
"DejaVu Sans"、"Noto Sans"、"Cantarell"
推荐写法(含回退):
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif;
}
注意:-apple-system 和 BlinkMacSystemFont 是特殊关键字,不是真实文件名,浏览器会自动映射到当前 macOS 或 Windows 的默认 UI 字体。
link + @font-face 才能加载自定义字体文件
如果你真有字体文件(比如从 Google Fonts 下载的 roboto-flex.woff2),需要用 <link rel="preload"> 配合 @font-face 声明:
先预加载(可选,优化性能):
<link rel="preload" href="/fonts/roboto-flex.woff2" as="font" type="font/woff2" crossorigin>
再在 CSS 中声明可用:
@font-face {
font-family: "Roboto Flex";
src: url("/fonts/roboto-flex.woff2") format("woff2");
font-weight: 100 900;
font-display: swap;
}
关键点:
-
crossorigin属性必须加在<link>上,否则字体加载会被 CORS 阻止 -
font-display: swap防止 FOIT(空白闪动),比block更实用 -
src路径必须可被浏览器直接请求,不能是本地绝对路径(如file:///C:/...)
为什么不能绕过限制调用系统字体文件
这是浏览器安全模型决定的:JavaScript 和 CSS 都无法枚举或读取用户磁盘上的字体列表,更不能构造路径去加载它们。所谓“系统字体”只是操作系统向渲染引擎暴露的一组命名接口,而非可访问的文件资源。
所以你看到的 "Microsoft YaHei" 能生效,是因为 Windows 系统注册了这个字体家族名,并由 DirectWrite(Windows)或 Core Text(macOS)提供渲染支持——你写的只是名字,不是路径。
如果用户系统里没装某个字体,又没配好 fallback,就只能降级到下一个;别指望用 <link> 强行“修复”。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











