bootstrap 5 字体未生效是因为其组件硬编码 font-family 且不继承 body,需重写 --bs-font-sans-serif 变量并确保加载顺序、@font-face 声明、preload 和组件兜底四者协同。

Bootstrap 5 的 font-family 规则优先级高、覆盖范围广,且不继承 body,你写的自定义字体样式大概率被它压住了——不是你写错了,是它“太用力”了。
为什么改了 body 字体却没用
Bootstrap 5 中的 .btn、.form-control、.dropdown-item、.modal-title 等组件,CSS 规则里都硬编码了 font-family,比如:
button, .btn { font-family: var(--bs-font-sans-serif); }
它们不写 inherit,也不依赖 body 的字体设置。所以哪怕你给 body 加了 font-family: "Noto Sans CJK SC",按钮和下拉项依然走 Bootstrap 自己的变量或回退链。
- 常见现象:正文显示思源黑体,但按钮文字还是
Segoe UI或Helvetica Neue - 根本原因:Bootstrap CSS 文件里这些类的规则权重高、位置靠后,且未声明
inherit - 别用
* { font-family: ... }——会污染第三方组件(比如 ECharts、Tinymce)
怎么安全重写 --bs-font-sans-serif 变量
这是最省事的全局方案,但必须卡死两个前提:加载顺序 + @font-face 声明。
- 自定义 CSS 必须放在
bootstrap.min.css的<link>之后,否则变量根本不会生效 - 写法示例(注意引号和正式字体名):
:root { --bs-font-sans-serif: "Noto Sans CJK SC", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; } - 某些组件(如
.form-select)在 Safari/Firefox 中会忽略该变量,得额外补一句:.form-select { font-family: var(--bs-font-sans-serif); } - 中文字体名必须用正式名称:
"Noto Sans CJK SC",不是"Source Han Sans"或"思源黑体",更不能用 Unicode 编码(如\5b8b\4f53)
字体“设了却像没设”——其实是加载策略问题
用户看到的“先是宋体,闪一下变黑体”,不是 CSS 失效,是字体文件还没下载完,浏览器先用了系统字体渲染。这会导致布局偏移(FOIT/FOUT)。
- 必须配
@font-face声明,并带font-display: swap:@font-face { font-family: "Noto Sans CJK SC"; src: url("/fonts/noto-sans-sc.woff2") format("woff2"); font-display: swap; } - 在
加预加载:<link rel="preload" href="/fonts/noto-sans-sc.woff2" as="font" type="font/woff2" crossorigin>
- 中文字体全量体积大(>1MB),建议子集化,或用 baomitu.com 提供的精简 CDN 版本
真正麻烦的不是写几行 CSS,而是把 @font-face、preload、变量重写、组件兜底这四件事串成一条不掉链子的加载流水线——漏一环,字体就“看起来没生效”。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











