字体系统完整指南
目录
- 字体基础概念
- @font-face 字体定义
- font-family 字体使用
- font-weight 字体粗细
- 字体回退机制
- 字体加载与性能
- 实际应用示例
- 最佳实践
1. 字体基础概念
什么是字体?
字体(Font)是一套具有相同设计风格的字符集合,包括字母、数字、标点符号等。每个字体都有其独特的视觉特征。
1.1 字体分类
1.1.1 按字符宽度分类
-
等宽字体(Monospace):每个字符占用相同宽度
- 适用于:代码、表格、数据对齐
- 示例:JetBrains Mono、Fira Code、Source Code Pro
-
比例字体(Proportional):字符宽度根据实际形状调整
- 适用于:正文、标题、界面文本
- 示例:Inter、Arial、Helvetica
1.1.2 按衬线分类
-
衬线字体(Serif):字符末端有装饰性线条
- 特点:传统、正式、易读
- 示例:Times New Roman、Georgia
-
无衬线字体(Sans-serif):字符末端无装饰
- 特点:现代、简洁、清晰
- 示例:Arial、Helvetica、Inter
1.1.3 按语言支持分类
- 单语言字体:主要支持一种语言
- 多语言字体:支持多种语言字符
- 示例:Noto Sans SC(支持中英文)、Ubuntu(支持多语言)
2. @font-face 字体定义
2.1 基本语法
@font-face {font-family: '字体名称';font-style: normal | italic | oblique;font-weight: 100-900 | normal | bold;font-display: auto | block | swap | fallback | optional;src: url('字体文件路径') format('字体格式');
}
2.2 详细参数说明
2.2.1 font-family
- 作用:为字体定义一个名称,供 font-family 属性使用
- 命名规则:建议使用有意义的名称,避免与系统字体冲突
- 示例:
@font-face {font-family: 'MyCustomFont'; /* 自定义名称 */src: url('./my-font.ttf');
}
2.2.2 font-style
- normal:正常样式(默认)
- italic:斜体样式
- oblique:倾斜样式
@font-face {font-family: 'Inter';font-style: normal;src: url('./Inter-Regular.ttf');
}@font-face {font-family: 'Inter';font-style: italic;src: url('./Inter-Italic.ttf');
}
2.2.3 font-weight
- 数字值:100-900(推荐)
- 关键词:normal(400)、bold(700)
@font-face {font-family: 'Inter';font-weight: 400;src: url('./Inter-Regular.ttf');
}@font-face {font-family: 'Inter';font-weight: 700;src: url('./Inter-Bold.ttf');
}
2.2.4 font-display
控制字体加载时的显示行为:
- auto:浏览器默认行为
- block:字体加载期间隐藏文本(最长3秒)
- swap:立即显示回退字体,字体加载后替换
- fallback:短暂隐藏文本(100ms),然后显示回退字体
- optional:字体加载失败时使用回退字体
@font-face {font-family: 'Inter';src: url('./Inter-Regular.ttf');font-display: swap; /* 推荐用于正文字体 */
}
2.2.5 src 和 format
- url():指定字体文件路径
- format():指定字体格式(可选,但推荐)
@font-face {font-family: 'Inter';src:url('./Inter-Regular.woff2') format('woff2'),url('./Inter-Regular.woff') format('woff'),url('./Inter-Regular.ttf') format('truetype');
}
2.3 完整示例
@font-face {font-family: 'Noto Sans SC';font-style: normal;font-weight: 400;font-display: swap;src:url('./Noto-Sans-SC-Regular.woff2') format('woff2'),url('./Noto-Sans-SC-Regular.woff') format('woff'),url('./Noto-Sans-SC-Regular.ttf') format('truetype');
}@font-face {font-family: 'Noto Sans SC';font-style: normal;font-weight: 700;font-display: swap;src:url('./Noto-Sans-SC-Bold.woff2') format('woff2'),url('./Noto-Sans-SC-Bold.woff') format('woff'),url('./Noto-Sans-SC-Bold.ttf') format('truetype');
}
3. font-family 字体使用
3.1 基本语法
font-family: 字体1, 字体2, 字体3, 通用字体族;
3.2 字体回退机制
3.2.1 工作原理
浏览器按照从左到右的顺序尝试字体:
- 检查系统是否有第一个字体
- 如果有,使用它渲染所有字符
- 如果没有,尝试下一个字体
- 如果都没有,使用通用字体族
3.2.2 示例分析
font-family: 'Noto Sans SC', Ubuntu, sans-serif;
执行流程:
- 检查系统是否有 “Noto Sans SC”
- 如果有 → 使用 “Noto Sans SC” 渲染所有文本
- 如果没有 → 检查 Ubuntu
- 如果有 Ubuntu → 使用 Ubuntu 渲染所有文本
- 如果都没有 → 使用系统默认 sans-serif 字体
3.3 通用字体族
3.3.1 serif(衬线字体)
font-family: 'Times New Roman', serif;
- Windows:Times New Roman
- macOS:Times
- Linux:Liberation Serif
3.3.2 sans-serif(无衬线字体)
font-family: 'Arial', sans-serif;
- Windows:Arial
- macOS:Helvetica
- Linux:Liberation Sans
3.3.3 monospace(等宽字体)
font-family: 'Courier New', monospace;
- Windows:Courier New
- macOS:Monaco
- Linux:Liberation Mono
3.3.4 cursive(手写体)
font-family: 'Brush Script MT', cursive;
3.3.5 fantasy(装饰体)
font-family: 'Impact', fantasy;
3.4 字体名称规则
3.4.1 包含空格的字体名
font-family: 'Times New Roman', serif; /* 必须加引号 */
3.4.2 不包含空格的字体名
font-family: Arial, sans-serif; /* 可以不加引号 */
font-family: 'Arial', sans-serif; /* 加引号也可以 */
3.4.3 通用字体族
font-family: Arial, sans-serif; /* 通用字体族不加引号 */
3.5 实际应用示例
3.5.1 中英文混排
body {font-family:'Noto Sans SC', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei',sans-serif;
}
3.5.2 代码字体
code {font-family:'JetBrains Mono', 'Fira Code', 'Source Code Pro', 'Consolas', monospace;
}
3.5.3 界面字体
.ui-text {font-family:-apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif;
}
4. font-weight 字体粗细
4.1 数字值(推荐)
font-weight: 100; /* 最细 - Thin */
font-weight: 200; /* 超细 - Extra Light */
font-weight: 300; /* 细体 - Light */
font-weight: 400; /* 正常 - Regular/Normal */
font-weight: 500; /* 中等 - Medium */
font-weight: 600; /* 半粗 - Semi Bold */
font-weight: 700; /* 粗体 - Bold */
font-weight: 800; /* 超粗 - Extra Bold */
font-weight: 900; /* 最粗 - Black */
4.2 关键词
font-weight: normal; /* 等同于 400 */
font-weight: bold; /* 等同于 700 */
font-weight: lighter; /* 比父元素更细 */
font-weight: bolder; /* 比父元素更粗 */
4.3 与 @font-face 配合使用
4.3.1 定义不同粗细的字体
@font-face {font-family: 'Inter';font-weight: 300;src: url('./Inter-Light.ttf');
}@font-face {font-family: 'Inter';font-weight: 400;src: url('./Inter-Regular.ttf');
}@font-face {font-family: 'Inter';font-weight: 700;src: url('./Inter-Bold.ttf');
}
4.3.2 使用不同粗细
.light-text {font-family: 'Inter', sans-serif;font-weight: 300;
}.normal-text {font-family: 'Inter', sans-serif;font-weight: 400;
}.bold-text {font-family: 'Inter', sans-serif;font-weight: 700;
}
4.4 浏览器行为
4.4.1 有对应字体文件
font-family: 'Inter';
font-weight: 700;
- 浏览器使用
Inter-Bold.ttf
文件 - 显示效果最佳
4.4.2 没有对应字体文件
font-family: Arial;
font-weight: 700;
- 浏览器使用 Arial 字体
- 人工加粗处理(效果可能不如专门的粗体文件)
5. 字体回退机制
5.1 字符级 vs 字体级回退
5.1.1 字体级回退(默认行为)
font-family: 'Noto Sans SC', Arial, sans-serif;
- 浏览器选择第一个可用的字体文件
- 用该字体渲染所有字符
- 如果字体不支持某个字符,显示为默认字符或方块
5.1.2 字符级回退(需要特殊配置)
@font-face {font-family: 'MixedFont';src: local('ChineseFont');unicode-range: U+4E00-9FFF; /* 中文字符范围 */
}@font-face {font-family: 'MixedFont';src: local('EnglishFont');unicode-range: U+0000-007F; /* 英文字符范围 */
}.text {font-family: 'MixedFont', sans-serif;
}
5.2 现代字体的多语言支持
5.2.1 多语言字体特点
- Noto Sans SC:支持中文、英文、数字、符号
- Ubuntu:支持多种语言字符
- Inter:专为屏幕显示优化,支持多语言
5.2.2 推荐的多语言字体组合
/* 中英文混排 */
body {font-family:'Noto Sans SC','PingFang SC','Hiragino Sans GB','Microsoft YaHei',-apple-system,BlinkMacSystemFont,sans-serif;
}/* 代码字体 */
code {font-family:'JetBrains Mono', 'Fira Code', 'Source Code Pro', 'Consolas', 'Monaco',monospace;
}
6. 字体加载与性能
6.1 字体文件格式
6.1.1 WOFF2(推荐)
- 优点:压缩率最高,加载最快
- 支持:现代浏览器
- 文件大小:比 TTF 小 30-50%
6.1.2 WOFF
- 优点:压缩率较高,兼容性好
- 支持:IE9+ 及现代浏览器
- 文件大小:比 TTF 小 20-30%
6.1.3 TTF/OTF
- 优点:兼容性最好
- 缺点:文件较大
- 用途:作为最后的回退格式
6.1.4 EOT
- 用途:仅用于旧版 IE
- 现状:基本不再使用
6.2 字体加载策略
6.2.1 预加载(Preload)
<linkrel="preload"href="./fonts/Inter-Regular.woff2"as="font"type="font/woff2"crossorigin
/>
6.2.2 字体显示策略
@font-face {font-family: 'Inter';src: url('./Inter-Regular.woff2') format('woff2');font-display: swap; /* 立即显示回退字体 */
}
6.2.3 字体子集化
/* 只包含需要的字符 */
@font-face {font-family: 'Inter';src: url('./Inter-Subset.woff2') format('woff2');unicode-range: U+0000-007F; /* 仅英文字符 */
}
6.3 性能优化建议
6.3.1 使用现代格式
@font-face {font-family: 'Inter';src:url('./Inter-Regular.woff2') format('woff2'),url('./Inter-Regular.woff') format('woff'),url('./Inter-Regular.ttf') format('truetype');
}
6.3.2 合理使用 font-display
/* 正文字体 - 使用 swap */
@font-face {font-family: 'Inter';font-display: swap;
}/* 装饰字体 - 使用 optional */
@font-face {font-family: 'Decorative';font-display: optional;
}
6.3.3 避免过多字体
- 限制字体数量(建议不超过 3-4 个)
- 优先使用系统字体
- 考虑字体文件大小
7. 实际应用示例
7.1 完整的字体系统设置
7.1.1 CSS 变量定义
:root {/* 字体变量 */--font-body: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;--font-code: 'JetBrains Mono', 'Fira Code', 'Source Code Pro', monospace;--font-heading: 'Noto Sans SC', 'PingFang SC', 'Hiragino Sans GB', sans-serif;/* 字体大小 */--font-size-xs: 12px;--font-size-sm: 14px;--font-size-base: 16px;--font-size-lg: 18px;--font-size-xl: 20px;--font-size-2xl: 24px;--font-size-3xl: 30px;/* 行高 */--line-height-tight: 1.25;--line-height-normal: 1.5;--line-height-relaxed: 1.75;
}
7.1.2 字体定义
/* 正文字体 */
@font-face {font-family: 'Inter';font-style: normal;font-weight: 400;font-display: swap;src:url('./fonts/Inter-Regular.woff2') format('woff2'),url('./fonts/Inter-Regular.woff') format('woff');
}@font-face {font-family: 'Inter';font-style: normal;font-weight: 700;font-display: swap;src:url('./fonts/Inter-Bold.woff2') format('woff2'),url('./fonts/Inter-Bold.woff') format('woff');
}/* 代码字体 */
@font-face {font-family: 'JetBrains Mono';font-style: normal;font-weight: 400;font-display: swap;src: url('./fonts/JetBrainsMono-Regular.woff2') format('woff2');
}/* 中文字体 */
@font-face {font-family: 'Noto Sans SC';font-style: normal;font-weight: 400;font-display: swap;src: url('./fonts/Noto-Sans-SC-Regular.woff2') format('woff2');
}@font-face {font-family: 'Noto Sans SC';font-style: normal;font-weight: 700;font-display: swap;src: url('./fonts/Noto-Sans-SC-Bold.woff2') format('woff2');
}
7.1.3 使用示例
/* 基础样式 */
body {font-family: var(--font-body);font-size: var(--font-size-base);line-height: var(--line-height-normal);
}/* 标题样式 */
h1,
h2,
h3,
h4,
h5,
h6 {font-family: var(--font-heading);font-weight: 700;line-height: var(--line-height-tight);
}h1 {font-size: var(--font-size-3xl);
}
h2 {font-size: var(--font-size-2xl);
}
h3 {font-size: var(--font-size-xl);
}/* 代码样式 */
code,
pre {font-family: var(--font-code);font-size: var(--font-size-sm);line-height: var(--line-height-normal);
}/* 小文本 */
.small-text {font-size: var(--font-size-xs);line-height: var(--line-height-tight);
}/* 大文本 */
.large-text {font-size: var(--font-size-lg);line-height: var(--line-height-relaxed);
}
7.2 JavaScript 中的字体处理
7.2.1 读取 CSS 变量
// 获取字体设置
const bodyFont =getComputedStyle(document.documentElement).getPropertyValue('--font-body').trim() || '"Inter", sans-serif';const codeFont =getComputedStyle(document.documentElement).getPropertyValue('--font-code').trim() || '"JetBrains Mono", monospace';console.log('Body font:', bodyFont);
console.log('Code font:', codeFont);
7.2.2 动态字体加载
// 检查字体是否已加载
function isFontLoaded(fontFamily) {return document.fonts.check(`16px ${fontFamily}`);
}// 等待字体加载完成
async function waitForFont(fontFamily) {if (isFontLoaded(fontFamily)) {return true;}return new Promise(resolve => {document.fonts.ready.then(() => {resolve(isFontLoaded(fontFamily));});});
}// 使用示例
async function loadFonts() {await waitForFont('Inter');await waitForFont('JetBrains Mono');console.log('所有字体已加载完成');
}
7.3 响应式字体设计
7.3.1 使用 clamp() 实现响应式字体
:root {--font-size-base: clamp(14px, 2.5vw, 18px);--font-size-heading: clamp(20px, 4vw, 32px);
}body {font-size: var(--font-size-base);
}h1 {font-size: var(--font-size-heading);
}
7.3.2 媒体查询字体调整
/* 小屏幕 */
@media (max-width: 768px) {:root {--font-size-base: 14px;--line-height-normal: 1.6;}
}/* 大屏幕 */
@media (min-width: 1200px) {:root {--font-size-base: 18px;--line-height-normal: 1.5;}
}
8. 最佳实践
8.1 字体选择原则
8.1.1 可读性优先
- 选择易读的字体
- 考虑不同屏幕尺寸
- 测试不同背景色下的效果
8.1.2 性能考虑
- 优先使用系统字体
- 限制自定义字体数量
- 使用现代字体格式
8.1.3 品牌一致性
- 与设计系统保持一致
- 考虑品牌调性
- 建立字体层级
8.2 字体层级设计
8.2.1 建立清晰的层级
/* 字体大小层级 */
--font-size-xs: 12px; /* 辅助信息 */
--font-size-sm: 14px; /* 小文本 */
--font-size-base: 16px; /* 正文 */
--font-size-lg: 18px; /* 大文本 */
--font-size-xl: 20px; /* 小标题 */
--font-size-2xl: 24px; /* 中标题 */
--font-size-3xl: 30px; /* 大标题 */
--font-size-4xl: 36px; /* 主标题 *//* 字重层级 */
--font-weight-light: 300;
--font-weight-normal: 400;
--font-weight-medium: 500;
--font-weight-semibold: 600;
--font-weight-bold: 700;
8.3 跨平台兼容性
8.3.1 系统字体回退
/* 界面字体 */
font-family:-apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Helvetica Neue',Arial, sans-serif;/* 代码字体 */
font-family:'SF Mono', 'Monaco', 'Inconsolata', 'Roboto Mono', 'Source Code Pro',monospace;/* 中文字体 */
font-family:'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei',sans-serif;
8.4 性能优化
8.4.1 字体加载优化
<!-- 预加载关键字体 -->
<linkrel="preload"href="./fonts/Inter-Regular.woff2"as="font"type="font/woff2"crossorigin
/>
<linkrel="preload"href="./fonts/Inter-Bold.woff2"as="font"type="font/woff2"crossorigin
/><!-- 非关键字体延迟加载 -->
<linkrel="preload"href="./fonts/Decorative.woff2"as="font"type="font/woff2"crossoriginmedia="print"onload="this.media='all'"
/>
8.4.2 CSS 优化
/* 使用 font-display: swap */
@font-face {font-family: 'Inter';font-display: swap;src: url('./fonts/Inter-Regular.woff2') format('woff2');
}/* 避免字体闪烁 */
.font-loading {font-family: system-ui, sans-serif;
}.font-loaded {font-family: 'Inter', system-ui, sans-serif;
}
8.5 测试与调试
8.5.1 字体加载检测
// 检测字体是否加载成功
function checkFontLoad(fontFamily) {const testString = 'abcdefghijklmnopqrstuvwxyz0123456789';const canvas = document.createElement('canvas');const context = canvas.getContext('2d');// 测试回退字体context.font = '16px monospace';const fallbackWidth = context.measureText(testString).width;// 测试目标字体context.font = `16px ${fontFamily}, monospace`;const targetWidth = context.measureText(testString).width;return targetWidth !== fallbackWidth;
}
8.5.2 字体性能监控
// 监控字体加载性能
const fontLoadObserver = new PerformanceObserver(list => {for (const entry of list.getEntries()) {if (entry.name.includes('font')) {console.log(`字体加载时间: ${entry.duration}ms`);}}
});fontLoadObserver.observe({ entryTypes: ['resource'] });
总结
字体系统是 Web 开发中的重要组成部分,正确理解和使用字体相关属性能够:
- 提升用户体验:选择合适的字体提高可读性
- 优化性能:合理加载字体减少页面加载时间
- 保持一致性:建立统一的字体层级和规范
- 增强可访问性:确保字体在不同设备和环境下都能正常显示
通过掌握 @font-face
、font-family
、font-weight
等核心概念,以及字体回退机制和性能优化技巧,可以构建出既美观又高效的字体系统。
记住:字体不仅仅是装饰,更是内容传达的重要载体。选择合适的字体,就是为用户提供更好的阅读体验。