Glittering's blog Glittering's blog
Home
  • 学习手册

    • 《JavaScript教程》
    • 《ES6 教程》
    • 《TypeScript 从零实现 axios》
    • 《Git》
    • TypeScript
    • CSS
  • 技术文档
  • 算法
  • 工作总结
  • 实用技巧
  • collect
About
  • Classification
  • Label
GitHub (opens new window)

Glitz Ma

前端开发工程师
Home
  • 学习手册

    • 《JavaScript教程》
    • 《ES6 教程》
    • 《TypeScript 从零实现 axios》
    • 《Git》
    • TypeScript
    • CSS
  • 技术文档
  • 算法
  • 工作总结
  • 实用技巧
  • collect
About
  • Classification
  • Label
GitHub (opens new window)
  • CSS

    • CSS教程和技巧收藏
    • css块元素和行内元素
    • 盒子模型
    • BFC和IFC
    • 字体font-weight相关知识
      • 一、基本概念:字体粗细的控制
      • 二、可取值类型(两种)
        • 关键字对应关系(大多数字体)
      • 三、数值映射(标准 9 级)
      • 四、字体文件对字重的支持
      • 五、font-weight 的继承规则
      • 六、现代字体技术:Variable Fonts(可变字体)
      • 七、实战:常见使用策略
        • 1️⃣ 全局字重控制(项目规范)
        • 2️⃣ 通过 Tailwind 控制(开发常用)
        • 3️⃣ 特殊字体匹配(中英混排优化)
      • 八、性能与渲染注意点
      • 九、面试常问总结
      • 十、知识图谱小结(结构化)
      • 十一、字体匹配算法
        • 一、为什么需要字体匹配算法?
        • 二、浏览器字体匹配算法的执行步骤
        • 1️⃣ 用户指定 font-family
        • 2️⃣ 字体候选查找(Font Family Matching)
        • 3️⃣ 字体样式匹配(Style Matching)
        • 4️⃣ 字符级别匹配(Glyph Fallback)
        • 5️⃣ 最终回退到通用字体族(Generic Families)
        • 三、简化模型总结(匹配逻辑图)
        • 四、实际应用中的问题与优化
        • 五、现代浏览器的扩展机制
        • ✅ 1. Local Font 优先级
        • ✅ 2. 字体合并(Font Fallback Chain)
        • ✅ 3. 字体缓存与预加载
        • 六、面试答题总结模板
    • CSS-function汇总
    • CSS3之has函数的使用
    • CSS3之transition过渡
    • CSS3之animation动画
    • css动画性能优化
    • flex布局语法
    • flex布局案例
    • Grid布局语法
    • flex布局和grid布局的区别
    • 「布局技巧」图片未加载前自动撑开元素高度
    • 文字在一行或多行时超出显示省略号
    • 水平垂直居中的几种方式-案例
    • 如何根据系统主题自动响应CSS深色模式
    • 工作中遇到的css问题记录
    • 今天总结一下用到的css吧
  • 页面
  • CSS
mamingjuan
2015-07-13
目录

字体font-weight相关知识

font-weight 是前端中看似简单、但实际上涉及到 浏览器渲染机制、字体文件特性、设计一致性 的重要知识点。 我们从基础语法到渲染原理、兼容与实战优化,一步讲清楚。


# 一、基本概念:字体粗细的控制

font-weight 用来定义字体的粗细(字重)。

font-weight: normal;
font-weight: bold;
font-weight: 500;
1
2
3

# 二、可取值类型(两种)

类型 示例 说明
关键字 normal, bold, bolder, lighter 通用值,可被继承和计算
数值 100 ~ 900(100 步进) 数值越大,字体越粗

# 关键字对应关系(大多数字体)

关键字 实际等价数值
normal 400
bold 700
bolder 比父元素更粗(非固定)
lighter 比父元素更细(非固定)

💡注意:bolder/lighter 是相对值,浏览器会根据父元素字重计算出一个近似等级。


# 三、数值映射(标准 9 级)

数值 英文名 中文说明
100 Thin / Hairline 极细体
200 Extra Light / Ultra Light 特细
300 Light 细体
400 Normal / Regular 常规体
500 Medium 中等
600 Semi Bold / Demi Bold 半粗
700 Bold 粗体
800 Extra Bold / Ultra Bold 特粗
900 Black / Heavy 黑体、超粗体

# 四、字体文件对字重的支持

⚠️ 重点陷阱!

并不是所有字体都支持 100~900 的全部字重。 很多字体只有少量样式,例如:

字体 可用字重
Arial 400, 700
Microsoft YaHei 微软雅黑 400, 700
PingFang SC 300, 400, 500, 600, 700
Roboto / Open Sans 全系支持
思源黑体(Noto Sans CJK) 100~900 全系列都有

如果设置一个字体不支持的字重,浏览器会自动选取最接近的可用字重。


# 五、font-weight 的继承规则

  • 默认情况下,font-weight 是 可继承属性。
  • 子元素未定义时,继承父元素的字重;
  • 若设置 bolder / lighter,会根据父级的 font-weight 相对调整:
父级字重 lighter bolder
≤ 100 100 400
200~300 100 500
400 300 700
500 400 800
600 400 900
≥ 700 400 900

# 六、现代字体技术:Variable Fonts(可变字体)

现代浏览器支持 可变字体(variable font),允许在一个字体文件内动态调整字重。

@font-face {
  font-family: 'Inter Variable';
  src: url('Inter-VariableFont_slnt,wght.ttf') format('truetype-variations');
  font-weight: 100 900; /* 支持范围 */
}

.text {
  font-family: 'Inter Variable';
  font-weight: 537; /* 任意数值都可渲染出真实粗细 */
}
1
2
3
4
5
6
7
8
9
10

💡 优点:

  • 一个文件支持所有字重;
  • 节省加载;
  • 支持动画(如字体渐变粗)。

# 七、实战:常见使用策略

# 1️⃣ 全局字重控制(项目规范)

body {
  font-weight: 400;
  font-family: 'PingFang SC', 'Helvetica Neue', Arial, sans-serif;
}
strong, b {
  font-weight: 600;
}
1
2
3
4
5
6
7

# 2️⃣ 通过 Tailwind 控制(开发常用)

<p class="font-light">Light 300</p>
<p class="font-normal">Normal 400</p>
<p class="font-medium">Medium 500</p>
<p class="font-bold">Bold 700</p>
1
2
3
4

# 3️⃣ 特殊字体匹配(中英混排优化)

.en {
  font-family: 'Roboto', sans-serif;
  font-weight: 500;
}
.cn {
  font-family: 'PingFang SC', 'Microsoft YaHei';
  font-weight: 400;
}
1
2
3
4
5
6
7
8

# 八、性能与渲染注意点

问题 原因 优化方式
页面字体闪烁(FOIT) 字体加载慢 使用 font-display: swap
文字变糊 / 抖动 某些字重 fallback 使用明确支持的字重
不同浏览器粗细不一致 渲染算法差异 明确声明字体族与字重
动画卡顿 字体重绘 减少字体 weight 动画或使用 variable font

# 九、面试常问总结

font-weight 用来设置字体的粗细,可以使用关键字(normal/bold)或数值(100~900)。 默认是 400,bold 对应 700。 但需要注意,不是所有字体都支持所有字重,比如微软雅黑只有 400 和 700。 如果设置了不支持的值,浏览器会自动匹配最接近的。 在现代项目中,我们会用 box-sizing: border-box 控制布局、用 font-weight: 400/500/700 区分层级; 而在可变字体(variable font)中,还可以精确控制任意字重,比如 font-weight: 537。


# 十、知识图谱小结(结构化)

font-weight
 ├── 类型
 │   ├── normal(400)
 │   ├── bold(700)
 │   ├── bolder/lighter(相对)
 │   └── 数值100-900
 ├── 字体支持范围
 │   ├── 部分字体仅支持400/700
 │   ├── 可变字体支持100-900
 ├── 继承规则
 │   ├── 可继承属性
 │   └── bolder/lighter按父级映射
 ├── 性能优化
 │   ├── font-display: swap
 │   └── 减少 weight 动画
 └── 实战
     ├── Tailwind font-*
     ├── 强调内容 bold/600
     └── 混排优化(中英字体分离)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 十一、字体匹配算法

“字体匹配算法(Font Matching Algorithm)” 是浏览器渲染文字时的一个核心机制, 它决定了:你在 CSS 里写的字体名,浏览器最终实际显示的字体是什么。


# 一、为什么需要字体匹配算法?

在 CSS 里你经常会写:

font-family: "PingFang SC", "Microsoft YaHei", Arial, sans-serif;
1

但并不是所有用户电脑或系统都有这些字体。 👉 所以浏览器要 从左到右 按规则查找“能显示该字符的字体”, 找不到就自动替换(fallback)到其他字体。

这整套逻辑,就是 字体匹配算法(font matching algorithm)。


# 二、浏览器字体匹配算法的执行步骤

以 Chrome 为例(其他浏览器机制大同小异)👇

# 1️⃣ 用户指定 font-family

浏览器会从 font-family 的候选列表开始,比如:

font-family: 'Roboto', 'PingFang SC', 'Helvetica', sans-serif;
1

会从左往右按以下顺序查找。


# 2️⃣ 字体候选查找(Font Family Matching)

浏览器在系统字体表中查找:

  • 是否存在 'Roboto'?
  • 如果存在,是否包含所需字符(例如中文)?

如果找不到,或找到了但不支持该字符,就继续下一个。

💡 一个字体文件可能不包含全部字符集。 例如 'Roboto' 没有中文字符,它就会 fallback 到 'PingFang SC'。


# 3️⃣ 字体样式匹配(Style Matching)

确定字体族后,浏览器会寻找与当前 CSS 属性最匹配的字体样式:

属性 匹配方向
font-style normal / italic / oblique
font-weight 100 ~ 900
font-stretch condensed / expanded
font-variant small-caps 等

算法会在字体文件中寻找最接近的样式:

例如你设了 font-weight: 500,但字体只提供 400 和 700, 浏览器就会选择更接近的那个(通常是 400)。


# 4️⃣ 字符级别匹配(Glyph Fallback)

如果字体支持部分字符,例如英文字母 ✅、中文 ❌, 浏览器会对“缺失字符”进行逐字符匹配:

每个字符都会被查找一遍,找到一个能渲染该字形(glyph)的字体。

这就是为什么你经常在英文 + 中文混排时发现“字体风格不一致”, 因为不同字符来自不同字体文件。


# 5️⃣ 最终回退到通用字体族(Generic Families)

如果上面的所有字体都找不到,浏览器就使用 通用字体族:

通用族 含义
serif 有衬线字体(宋体、Times)
sans-serif 无衬线字体(黑体、Arial)
monospace 等宽字体(Courier)
cursive 草书风格
fantasy 装饰性字体
system-ui 系统默认 UI 字体(如 SF Pro Text)

# 三、简化模型总结(匹配逻辑图)

font-family
 ├── 第 1 层:用户声明的字体族列表
 │     ├── 查找字体是否存在
 │     ├── 查找是否支持字符
 │     └── 若缺失则继续下一个
 ├── 第 2 层:字体样式匹配
 │     ├── 匹配 font-weight
 │     ├── 匹配 font-style
 │     └── 匹配 font-stretch
 ├── 第 3 层:逐字符匹配(Glyph fallback)
 └── 第 4 层:通用字体族 fallback(sans-serif 等)
1
2
3
4
5
6
7
8
9
10
11

# 四、实际应用中的问题与优化

问题 原因 优化建议
中文字体显示不统一 fallback 字体不同 明确声明中英文字体,如 "PingFang SC", "Microsoft YaHei", Arial
英文字母比中文细或偏移 字重差异 为中英文设置不同 font-family
英文字体 fallback 到宋体 缺少英文字体声明 添加英文字体如 "Helvetica", "Arial"
页面闪烁(FOIT/FOUT) 字体加载慢 使用 font-display: swap

# 五、现代浏览器的扩展机制

# ✅ 1. Local Font 优先级

如果字体名和系统内置字体重名(如 "Arial"), 浏览器会优先使用 本地版本(local)。

可以通过 @font-face 明确声明加载策略:

@font-face {
  font-family: 'MyFont';
  src: local('Arial'), url('MyFont.woff2') format('woff2');
}
1
2
3
4

# ✅ 2. 字体合并(Font Fallback Chain)

浏览器内部会自动维护一条 fallback 链,比如:

'Roboto' → 'Noto Sans' → 'PingFang SC' → 'sans-serif'

因此,有时即使没写 PingFang SC,Chrome 仍能正常显示中文。


# ✅ 3. 字体缓存与预加载

为防止字体闪烁(FOIT),可用:

font-display: swap;
1

或预加载字体:

<link rel="preload" href="font.woff2" as="font" type="font/woff2" crossorigin>
1

# 六、面试答题总结模板

浏览器的字体匹配算法是从开发者声明的 font-family 列表开始, 按顺序查找系统中存在且支持当前字符的字体文件。 找到字体后,会根据 font-weight、font-style 等属性选择最接近的样式; 如果该字体不支持某些字符,会进行逐字符 fallback; 最后再回退到通用字体族(如 sans-serif)。 在实际项目中,我们会通过明确的字体链、font-display、和中英文分组优化渲染一致性。


上次更新: 2025/11/25, 03:24:47
BFC和IFC
CSS-function汇总

← BFC和IFC CSS-function汇总→

Copyright © 2015-2025 Glitz Ma
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式