Source Sans 3 可变字体实战教程:用两个文件替代 14 个静态字体并解锁任意字重的完整方案
【免费下载链接】source-sansSans serif font family for user interface environments项目地址: https://gitcode.com/gh_mirrors/so/source-sans
Source Sans 3 是一款面向界面环境的开源无衬线字体家族,它的可变字体(Variable Fonts)版本把 200–900 的全部字重塞进两个文件。这篇文章不打算从头讲字体史,而是带你经历一次真实的改版:从"字重不够用"的烦恼开始,一路做到用两个文件驱动整站排版,中间踩过的坑都标给你看。
开场踩坑:为什么你的页面永远缺一个 500 字重 🎯
假设你在做一块数据看板。设计稿里,引导文案用了 500 的 Medium,按钮用了 650。你把项目里的source-sans-3.css引进来,写上font-weight: 500,打开页面一看——字是"厚"了,但笔画发虚,明显是浏览器把 400 强行加粗出来的假字(faux bold)。
打开 DevTools 的 Network 面板,你还会发现第二个真相:为了让页面同时出现 Light、Regular、Bold 几档字,浏览器已经默默下载了14 个静态 woff2 文件,合计约 1.3 MB。
反直觉的事实:静态方案里根本没有真正的 500 和 650。项目只提供 200、300、400、600、700、900 六档静态文件,其余字重全靠浏览器"演"。
你需要的不是再多加一个文件,而是换一种字体形态——可变字体(Variable Fonts)。
先算清这笔账:静态字体和可变字体到底差在哪
可变字体的核心概念很简单:一个文件里装的不是"一个字体",而是一条完整的"设计轴"。Source Sans 3 VF 只开了一条轴:wght(字重),范围 200–900。你可以把它想成音响上的音量旋钮——拧到任意位置,就能得到对应粗细的字体,中间不再有断档。
把项目里两套方案放在一起对比,差距一目了然:
| 方案 | 字体文件数 | WOFF2 总大小 | 可用的字重 |
|---|---|---|---|
静态版source-sans-3.css | 14 | 约 1.3 MB | 仅 6 档 |
可变版source-sans-3VF.css | 2 | 约 0.6 MB | 200–900 任意值 |
结论:文件数降到 1/7,体积省掉约 55%,能用的字重从 6 档变成 700 档(200 到 900 的每个整数)。这就是你改版的全部动机。
三分钟从克隆仓库到跑通:搭建最小可运行页面
先把仓库拿到本地,然后写一个最朴素的 HTML 来验证。
git clone https://gitcode.com/gh_mirrors/so/source-sans cd source-sans在项目根目录新建demo.html(必须放在根目录,因为 CSS 里的字体路径是相对 CSS 文件写的):
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>Source Sans 3 VF 字重阶梯</title> <link rel="stylesheet" href="source-sans-3VF.css"> <style> body { font-family: 'Source Sans 3 VF', sans-serif; } .w { font-size: 28px; margin: 6px 0; } </style> </head> <body> <p class="w" style="font-weight:200">200 ExtraLight</p> <p class="w" style="font-weight:400">400 Regular</p> <p class="w" style="font-weight:500">500 Medium(静态版给不了的真身)</p> <p class="w" style="font-weight:700">700 Bold</p> <p class="w" style="font-weight:900">900 Black</p> </body> </html>用浏览器打开这个文件。每一行都渲染成真实的字重,包括静态版无法提供的 500。
关键就在source-sans-3VF.css里这段声明,注意第 3 行的区间写法:
@font-face{ font-family: 'Source Sans 3 VF'; font-weight: 200 900; /* 区间写法:一个文件负责这一整段字重 */ font-style: normal; src: url('WOFF2/VF/SourceSans3VF-Upright.ttf.woff2') format('woff2-variations'), url('WOFF/VF/SourceSans3VF-Upright.ttf.woff') format('woff-variations'), url('VF/SourceSans3VF-Upright.ttf') format('truetype-variations'); }font-weight: 200 900是两个值,意思是"我这个文件能从 200 连续供到 900"。浏览器读到这个区间后,你写 537 这样的怪数字它也能渲染,因为可变字体会自动插值。
把字重变成可拖动的旋钮:CSS 变量加滑块实时调节
静态字体想换字重就得重新加载文件;可变字体不用——把字重接在一个滑块上,让它实时响应。这里用 CSS 变量 + 原生滑块,代码可以整段复制:
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>字重旋钮</title> <link rel="stylesheet" href="source-sans-3VF.css"> <style> :root { --fw: 400; } /* 唯一的"状态源" */ body { font-family: 'Source Sans 3 VF', sans-serif; } #preview { font-size: 42px; font-weight: var(--fw); } </style> </head> <body> <input type="range" id="weight" min="200" max="900" value="400"> <span id="label">400</span> <p id="preview">拖动上面的滑块,看着我的粗细变化</p> <script> const slider = document.getElementById('weight'); slider.addEventListener('input', function () { document.documentElement.style.setProperty('--fw', slider.value); document.getElementById('label').textContent = slider.value; }); </script> </body> </html>效果:拖动滑块,字重实时变化,全程零闪烁、零网络请求。采用 CSS 变量的好处是:JS 只负责写一个变量,字重的消费规则全留在 CSS 里——以后想加"暗色模式自动加重"之类的规则,都不用再动 JS。
排掉三个常见的坑:没有 ital 轴、没有 wdth 轴、老浏览器怎么办 ⚠️
网上的可变字体教程大多在讲ital轴和wdth轴,但那是别的字体。Source Sans 3 VF 的真实情况,我用工具读了一遍字体文件,只有一条wght轴。下面的坑你很可能踩到。
坑一:斜体是独立文件,不是轴。想要斜体,写font-style: italic即可,浏览器会自动命中 CSS 里第二个@font-face(italic 那一段,对应VF/SourceSans3VF-Italic.ttf)。千万不要写font-variation-settings: 'ital' 1,对这个字体是无效的。
坑二:wdth轴不存在。抄模板写'wdth' 110会被浏览器直接忽略。精细控制只认wght:
.hero { font-variation-settings: 'wght' 650; } /* 比 font-weight 更直接 */注意font-variation-settings的优先级高于font-weight,两者都写时以它为准。
坑三:老浏览器不认woff2-variations格式,会整段跳过。稳妥做法是静态版兜底、可变版增强:
<link rel="stylesheet" href="source-sans-3.css"> <!-- 静态版:老浏览器兜底 --> <link rel="stylesheet" href="source-sans-3VF.css"> <!-- 可变版:现代浏览器增强 -->@supports not (font-variation-settings: 'wght' 400) { body { font-family: 'Source Sans 3', sans-serif; } /* 走静态六档 */ }现代浏览器(Chrome 62+、Firefox 62+、Safari 11+、Edge 17+)都会命中可变版;老浏览器退到静态版,至少不白屏。
顺带一个设计软件的小知识:在 Figma 里直接打开VF/SourceSans3VF-Upright.ttf时,默认实例是 ExtraLight(200),记得把wght拖到目标值再取样式。
把可变字体放进真实项目:响应式排版与加载性能的取舍
跑通之后,就是把它变成生产可用方案的环节。
第一件事:给不同屏幕定字重策略。移动端屏幕小、分辨率高,过粗的字重反而发糊,通常降一档更好看:
h1 { font-weight: 800; } @media (max-width: 768px) { h1 { font-weight: 600; } /* 小屏降一档,避免粗字发糊 */ body { font-weight: 400; } }第二件事:组件级微调。可变字体的威力在于"细",按钮用 600、导航用 550、角标用 700,靠 50 的步进来铺层次,视觉密度会舒服很多。
第三件事:管好加载性能。几条实测建议:
- 网页只用
WOFF2/VF/里的文件(约 166 KB 一个),别直接引用 TTF(631 KB)。 - 首屏字体加 preload,尽早开始下载:
<link rel="preload" href="WOFF2/VF/SourceSans3VF-Upright.ttf.woff2" as="font" type="font/woff2" crossorigin>- 给
@font-face补上font-display: swap,加载期间先显示回退字体,避免文字隐形:
@font-face{ font-family: 'Source Sans 3 VF'; font-weight: 200 900; font-display: swap; /* 先渲染,字体到位再无缝替换 */ src: url('WOFF2/VF/SourceSans3VF-Upright.ttf.woff2') format('woff2-variations'); }这一套下来,整站字重相关资源从 1.3 MB 压到 0.6 MB 以内,且每个元素都能拿到精确字重。
接下来可以尝试什么:从设计软件到组件级字重控制
到这里,你已经走完了从踩坑到落地的全过程。下一步的延伸方向有三条:
- 改造现有项目:把 14 个静态
@font-face声明替换成 2 个 VF 声明,跑一遍 Lighthouse,对比体积与 FCP 的改善。 - 去设计软件里找手感:在 Figma 加载
VF/SourceSans3VF-Upright.ttf,拖动wght找出每个内容块"看起来最舒服"的字重,再回填到 CSS。 - 确认授权边界:商用前读一下 LICENSE.md,本项目采用 OFL-1.1,允许商用与再分发,保留版权声明即可;版本与维护信息见 package.json(当前 3.46.0)。
你接下来用得到的文件都在这:
- 可变字体 CSS:source-sans-3VF.css
- 静态对照版:source-sans-3.css
- 网页用字体文件:WOFF2/VF/
- 设计软件用原始文件:VF/
下次设计稿再丢来一个 537 的字重,你只需要把滑块拖过去——这就是把字重变成旋钮之后的日常。
【免费下载链接】source-sansSans serif font family for user interface environments项目地址: https://gitcode.com/gh_mirrors/so/source-sans
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考