简介:Font Awesome 4.7.0 是一套面向网页设计师与前端开发者的矢量图标字体库。它将图标封装为 Web 字体,可以像文字一样调整大小、颜色与清晰度,适配不同屏幕分辨率,特别适合响应式界面、后台管理及移动端页面,避免传统图片图标缩放失真的问题。压缩包共 37 个文件,核心包括 14 个 SCSS 与 14 个 LESS 源文件,方便使用 Sass/LESS 预处理器定制图标样式;另外配有 2 个 CSS 成品样式表,以及 eot、ttf、woff、woff2、svg、otf 六种字体格式,基本覆盖新旧浏览器兼容需求;整包仅 654KB,引入成本极低。目前已有 946 人学习下载,对于不需要最新特性的中小型项目来说,这个版本成熟稳定、社区资料多,是省心的选择。该版本支持通过 fa fa-search 这类类名快速调用图标,fa-lg、fa-2x 控制尺寸,fa-flip-horizontal、fa-flip-vertical 实现翻转;包内附有使用说明文件,便于快速了解类名规则与引用注意事项,缩短接入时间。
1. font-awesome 4.7.0 是谁:还在老项目里跑着的图标字体
接手一个 2017 年就开始跑的内部管理后台,模板文件里到处都是<i class="fa fa-pencil"></i>,部署包里躺着一个 font-awesome-4.7.0 文件夹。这就是本文要讲的东西:Font Awesome 4.x 的最后一个版本,发布于 2017 年,一共 675 个图标,用「字体 + CSS 伪元素」的方式在网页里渲染图标,不依赖任何 JavaScript,也没有 SVG 雪碧图那套复杂流程。
它的价值不在“新”,而在“存量”:大量老系统、外包项目、Bootstrap 3 后台模板到今天还在用它。你搜索 font-awesome-4.7.0,大概率是遇到了三种情况:本地部署时字体加载不出来、准备把它接进新的构建工程、或者要从 4.7.0 迁移到 5.x/6.x。这篇文章会把这三条路都走一遍,包括部署的每个命令、参数的来龙去脉,以及我在实际项目里踩过的坑。
2. 本地部署 font-awesome 4.7.0:目录、路径和最小页面
2.1 下载和目录:5 类文件各管什么
常见做法是从官方 GitHub 的 release 里下载font-awesome-4.7.0.zip,或者直接拿 CDN 上同版本的文件落盘。解压后你会看到这样的目录结构:
| 文件/目录 | 作用 | 我们为什么需要它 |
|---|---|---|
css/font-awesome.css | 全部图标的 class 声明,含@font-face | 页面里必须引用的样式 |
css/font-awesome.min.css | 压缩版,生产环境用这个 | 体积小一半,建议直接用 |
fonts/fontawesome-webfont.woff2 | 现代浏览器用的图标字体 | 页面渲染图标的真正载体 |
fonts/fontawesome-webfont.woff | 老浏览器回退 | 要不要保留看你的兼容范围 |
fonts/fontawesome-webfont.ttf | 老 Safari、桌面端兼容 | 要兼容旧系统时保留 |
less/、scss/ | 源样式,可编译定制 | 只有你想改主题色时用得到 |
下载后第一件事不是急着往项目里复制,而是先确认字体文件没被系统“帮忙”改成 0 字节。Windows 下载 zip 再解压一般没事,但如果你是从即时通讯软件里转发的安装包,偶尔会出现解压后woff2文件损坏的情况,后面所有图标都会变成方块。我一般会顺手看一眼fonts目录下每个文件的大小,低于 10KB 的字体文件基本就是坏了。
2.2 最小 HTML 页面:先确认字体能加载再接入工程
把css和fonts两个目录原样拷进项目后,先做一个最小页面验证,不要直接往老系统里塞,否则出了问题分不清是路径错了还是被其他样式污染。在项目根目录新建一个test-fa.html:
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>Font Awesome 4.7.0 本地验证</title> <link rel="stylesheet" href="css/font-awesome.min.css"> </head> <body> <p><i class="fa fa-camera-retro"></i> 相机图标</p> <p><i class="fa fa-cog fa-spin"></i> 旋转设置</p> <p><i class="fa fa-address-book"></i> 通讯录</p> <p><i class="fa fa-user-circle-o"></i> 用户</p> </body> </html>用浏览器直接打开这个文件通常看不到图标,因为file://协议下浏览器会拦截字体文件加载。正确做法是起一个本地静态服务,在项目根目录执行:
python3 -m http.server 8080然后浏览器访问http://localhost:8080/test-fa.html。看到四个图标正常渲染,说明部署路径没问题。这里的关键逻辑是:Font Awesome 4.7.0 的所有图标 class,本质是通过:before伪元素往页面里塞一个字符,这个字符落在FontAwesome字体里,字体加载失败,字符就显示成方块或空白。
2.3 css 与 fonts 的相对路径:字体 404 的最常见来源
很多人把font-awesome.min.css复制到任意目录,比如放进css/plugins/,但字体文件还留在原来的fonts/下,于是页面 404。原因在于font-awesome.min.css内部的@font-face是这么写的:
@font-face { font-family: 'FontAwesome'; src: url('../fonts/fontawesome-webfont.eot?v=4.7.0'); src: url('../fonts/fontawesome-webfont.eot?#iefix&v=4.7.0') format('embedded-opentype'), url('../fonts/fontawesome-webfont.woff2?v=4.7.0') format('woff2'), url('../fonts/fontawesome-webfont.woff?v=4.7.0') format('woff'), url('../fonts/fontawesome-webfont.ttf?v=4.7.0') format('truetype'); }这里的../fonts/是相对于 CSS 文件所在目录解析的。CSS 在css/下,那字体就在项目根的fonts/下。你要么保持 css 和 fonts 的原始相对位置,要么手动把这段@font-face里的路径改掉。另一个高频问题是服务器 MIME 类型没配,Nginx 默认不认识woff2,会把字体请求返回成application/octet-stream,部分浏览器直接拒绝加载。在 Nginx 的http块里补上:
types { font/woff2 woff2; font/woff woff; font/ttf ttf; }改完nginx -t检查配置再nginx -s reload。这一步做完,本地部署的 90% 问题都解决了。
3. 把 font-awesome 4.7.0 接进 CDN、Bootstrap 3 和 webpack
3.1 用 CDN 一步接入:路径规律与版本锁定的注意点
如果老系统没有离线要求,最省事的方式是直接引 CDN。市面上主流 CDN 对 font-awesome 4.7.0 的路径大体都是/font-awesome@4.7.0/css/font-awesome.min.css这种结构,注意两点:一是版本号必须写死@4.7.0,不要写@4或latest,否则升级后 class 断裂你根本不知道;二是确认你的 CDN 支持woff2的 MIME,否则效果和本地部署那个坑一样。
我一般会这样写:
<link rel="stylesheet" href="https://unpkg.com/font-awesome@4.7.0/css/font-awesome.min.css">但这里有个风险:老项目如果还有原因是历史遗留的 HTTP 页面,从 HTTPS CDN 引字体没问题,反过来就会触发混合内容拦截,后面第 4 章专门讲。CDN 方式适合临时验证和原型页面,正式环境我还是建议把文件下到本地,毕竟你没法控制上游 CDN 哪天把 4.7.0 下架。
3.2 在 Bootstrap 3 布局里对齐图标:fa-fw / fa-ul 的实际用法
Font Awesome 4.7.0 发布时主要搭配 Bootstrap 3 使用,两者的 class 体系配合得很默契。后端管理系统最常见的场景是导航菜单和表单按钮,直接写<i class="fa fa-gear"></i> 系统设置也能用,但图标宽度不一致,菜单竖排后错落感很明显。这时要用fa-fw固定宽度:
<ul class="nav nav-sidebar"> <li><a href="#"><i class="fa fa-dashboard fa-fw"></i> 控制台</a></li> <li><a href="#"><i class="fa fa-users fa-fw"></i> 用户管理</a></li> <li><a href="#"><i class="fa fa-file-text-o fa-fw"></i> 内容列表</a></li> </ul>fa-fw的原理是把伪元素生成的图标字符放在一个固定宽度容器里,约 1.285714em,所有图标按同一个宽度左对齐,文字自然对齐。这个参数在 4.7.0 的 CSS 里已经内置,直接fa fa-xxx fa-fw三个类叠加就行,不需要额外写样式。
表单按钮要注意另一个场景:Bootstrap 3 的btn自带line-height和font-family,如果按钮里图标偶尔和文字错位,给i元素加一行vertical-align: -2px就回来了。这里不推荐再包一层 span,老项目改起来成本高。
3.3 在 webpack 5 / Vite 项目里接管字体文件
把 4.7.0 接进现代构建工程时,最常遇到的报错是Module parse failed,原因是 webpack 不知道如何处理woff2文件。webpack 5 的正确做法是把它声明成静态资源:
// webpack.config.js 片段 module.exports = { module: { rules: [ { test: /\.(woff2?|eot|ttf|otf|svg)(\?.*)?$/, type: 'asset/resource', generator: { filename: 'fonts/[name].[ext]' } } ] } };这段配置会把字体文件原样拷贝到构建产物的fonts/目录,同时把 CSS 里@font-face的 url 重写成带哈希的最终路径。注意test正则里的(\?.*)?不能省,Font Awesome 4.7.0 的字体路径里带?v=4.7.0查询参数,webpack 解析时要先剥离掉。
在入口文件里直接引入 CSS:
import 'font-awesome/css/font-awesome.min.css';如果你用的是 Vite,简单得多,把fonts目录放到public/下,CSS 用%BASE_URL%fonts/fontawesome-webfont.woff2这类写法,或者直接把整个 font-awesome 目录放 public,然后link引用。Vite 对相对路径的@font-face支持不算好,我建议快速集成时用 public 目录方案,少踩很多资源解析的坑。
4. font-awesome 4.7.0 图标不显示排查:方块、乱码和混用的 5 个坑
4.1 空心方块:字体文件没被加载或 MIME 不对
现象:页面其他正常,所有图标渲染成一个小方框,控制台 Network 面板里字体请求状态是 404,或者请求成功但Content-Type是application/octet-stream。
原因:@font-face里定义的字体文件路径错了,或者服务器没有正确返回字体 MIME。这是 Font Awesome 部署的头号翻车点。
解决:按第 2.3 节核对 CSS 与 fonts 的相对路径,再检查服务器 MIME 配置。用 Nginx 的话,gzip_types里也要补font/woff2,否则即使字体加载了,配合 gzip 也可能出现响应异常。改完后强制刷新浏览器,清掉缓存的 404 结果再验证。
4.2 方框问号:content 码位和字体对不上
现象:图标显示成带问号的方框,或一个奇怪的字符,字体请求是 200。
原因:你把 5.x 的 class 用在了 4.7.0 的 CSS 上,比如写了fas fa-user,4.7.0 不认识fas,伪元素没生效;或者写了fa fa-user-circle,4.7.0 里有这个 class,但它对应的 content 码位在 4.7.0 的字体里没有字形。
解决:先用浏览器开发者工具选中这个i标签,看伪元素content的最终值,再打开font-awesome.min.css搜.fa-user-circle:before,比对 content 是否一致。不一致说明你引用的 CSS 版本和字体文件版本不是同一套。用 4.7.0 的 CSS 就必须配 4.7.0 的字体文件,混一个都不行。这条也是我排查乱码时第一个验证的点。
4.3 整体错乱:页面同时加载了 4.7.0 和 5.x
现象:部分图标正常,部分图标变成另一种风格,有时加了fa-前缀的图标全都变细、不填充。
原因:页面里同时引入了 font-awesome 4.7.0 和 5.x/6.x 的 CSS。两个版本的@font-face都定义了FontAwesome,后加载的覆盖先加载的,而 5.x 的图标字体编码和 4.x 并不完全兼容。
解决:同一页面只能保留一个版本。如果确实有第三方组件强制引入了 5.x,给 4.7.0 的样式单独包一个作用域,比如给页面根节点加class="fa4",然后手动把 4.7.0 的 CSS 里所有.fa写成.fa4 .fa。注意 4.7.0 的.btn .fa这种组合也要一并处理,工作量不如直接统一版本,能升级就升级,不能升级就尽量隔离。
4.4 垂直对不齐:FontAwesome 字体参与行高计算
现象:图标和旁边文字基线差两三个像素,尤其在 Bootstrap 3 的按钮和表格里明显。
原因:FontAwesome 字体本身的 ascender 和 descender 指标不同于系统字体,服务端渲染时浏览器按字体指标计算行盒高度。
解决:给图标设置固定行高并调整垂直对齐:
i.fa { line-height: 1; vertical-align: -2px; }注意这个调整要对标签自身做,不能放在父元素上,否则所有文字都跟着变。表格场景里再配合fa-fw一起用,基本能压住错位。这块纯属玄学,不同操作系统下渲染结果都有差异,我用的是 Windows Chrome 和 macOS Safari 双端确认过的值,Linux 上差的像素会多一点。
4.5 HTTPS 页面里混入 HTTP 字体被浏览器拦截
现象:本地部署正常,一到线上测试环境图标全丢,控制台提示Mixed Content。
原因:老系统经常是反向代理配置不完整,页面是 HTTPS,但 CSS 里的字体 url 写成了http://,现代浏览器默认拦截所有混合内容,woff2也在拦截范围内。
解决:把 font-awesome 目录放到同域下,用相对路径引用css/font-awesome.min.css,不要写带协议的绝对地址。如果必须从另一个域名加载字体,那个域名也要支持 HTTPS,并且响应头里的Access-Control-Allow-Origin得允许你的页面来源。这个坑排查起来很隐蔽,因为 Network 面板有时只显示一个黄色警告,不会标红。
5. 从 font-awesome 4.7.0 迁移到 5/6:类名映射表与回归验证
5.1 类名为什么断:4.x 的 .fa 前缀和 5/6 的 family 体系
4.7.0 只有一个前缀fa,所有图标都写成fa fa-xxx。5.0 之后 Font Awesome 把图标拆成 solid、regular、brands 等几种风格,分别用fas、far、fab前缀,并且把免费版和 Pro 版的体系彻底分开。这导致大量 4.x 类名在 5/6 里要么改了前缀,要么改了名字,要么从免费变成了付费。
迁移不是把fa fa-替换成fas fa-就完事,因为很多图标在 4.x 里用-o后缀表示空心样式,在 5/6 里直接用far前缀表达,图标名字也变了。典型如fa fa-file-text-o在 4.7.0 里是空心文件加文字,5/6 里要写far fa-file-alt。不做映射表直接全局替换,迁移完你只会得到满屏方框。
5.2 高频类名映射表:直接照着改
我在多个项目里整理过一份高频对照,覆盖后台管理系统的常见场景:
| 4.7.0 写法 | 5/6 免费版写法 | 说明 |
|---|---|---|
fa fa-user-circle-o | far fa-user-circle | 空心圆头像变 regular 风格 |
fa fa-trash-o | far fa-trash-alt | 删除按钮空心变细线 |
fa fa-warning | fas fa-exclamation-triangle | 别名在 5/6 中不再可用 |
fa fa-address-book-o | far fa-address-book | -o后缀统一去掉 |
fa fa-facebook-official | fab fa-facebook | 品牌图标进 brands 族 |
fa fa-wechat | fab fa-weixin | 名称改为拼音原名 |
fa fa-calendar-check-o | far fa-calendar-check | 事件日历类 |
fa fa-reorder | fas fa-bars | 列表排序图标改名 |
fa fa-gear | fas fa-cog | 老别名在 5/6 已移除 |
fa fa-times-circle-o | far fa-times-circle | 关闭按钮常见写法 |
迁移前先在页面里全局搜索fa fa-,把数量统计出来,再按这个表格逐项替换。如果你用的图标多,建议把整个font-awesome.css里 4.7.0 的 content 映射导出来,和 6 的码表做一次程序化比对,而不是纯手工改。
5.3 批量统计与回归验证:迁移不是换 css 就完事
迁移过程中最容易漏的是动态渲染的图标类名,比如后端接口返回icon: "fa fa-user",前端直接拼到模板里。这种你替换 HTML 和前端模板都没用,得在渲染层做一层映射。我一般先写个脚本把所有老类名从代码里揪出来:
import re from pathlib import Path # 统计整个项目里出现过的 font-awesome 4.x 类名 pattern = re.compile(r'fa fa-[a-z0-9-]+') found = set() for path in Path('templates').rglob('*.html'): found.update(pattern.findall(path.read_text(encoding='utf-8'))) for item in sorted(found): print(item)这个脚本会把templates目录下所有 HTML 模板里的老写法列出来。迁移完成后,把 CSS 换成 5/6,再跑一遍脚本,用之前登记的每一条类名对照映射表检查是否都已经换成fas/far/fab开头。重点看那些没进映射表的名字,它们大概率是品牌图标或 Pro 图标,免费版里没有对应,需要找替代图标。
回归验证别只在首页看,要专门打开几个带表格、表单、导航的页面截图。图标类名替换后,布局不会变,但是图标视觉风格从实心变空心或从空心变细线,用户感知很明显。截图对比能发现这类细节。
6. 给 font-awesome 4.7.0 做子集化:一个脚本裁掉用不上的字体
6.1 提取 css 里的码位:用 Python 生成 pyftsubset 参数
老项目可能只用了 675 个图标里的三四十个,却要下载完整的woff2字体。如果系统部署在内网,字体文件虽然不大,但每次改版都要上传到多台服务器,还是有点疼。Font Awesome 4.7.0 的字体可以用pyftsubset裁剪。先把 CSS 里用到的码位提取出来:
import re from pathlib import Path css_path = Path('font-awesome.min.css') css = css_path.read_text(encoding='utf-8') # 匹配 .fa-icon-name:before { content: "\fxxx"; } pattern = re.compile(r'\.fa-([a-z0-9-]+):before\s*\{\s*content:\s*"\\f([0-9a-f]+)"', re.I) unicodes = sorted({int(code, 16) for _, code in pattern.findall(css)}) # 输出给 pyftsubset 用的参数格式 print(','.join(f'U+{code:04X}' for code in unicodes))然后安装 fonttools 并执行子集化:
pip install fonttools[woff] pyftsubset fontawesome-webfont.ttf \ --unicodes=U+f000,U+f001,U+f013,U+f030 \ --flavor=woff2 \ --output-file=fontawesome-webfont.subset.woff2--unicodes参数来自上面 Python 脚本的输出,只保留实际声明了伪元素的码位;--flavor=woff2指生成 woff2 格式。注意我这里示例只写了 4 个码位,实际要用脚本输出的完整列表。
6.2 替换字体并核对在用图标
生成的fontawesome-webfont.subset.woff2替换原字体文件时,要把 CSS 里@font-face的 url 改成这个文件,其余逻辑不用动。验证方法很直接:写一个页面,把项目里用到的所有fa fa-xxx列出来,对照静态页面检查每个图标是否还正常显示。
这个技巧最大的价值在于让 4.7.0 这种老资源在带宽受限的内网环境里跑得更轻。我第一次这么干是在一个审批系统上,字体文件从原来的两百多 KB 降到不到三十 KB,部署包明显变小。但要注意,如果模板里用content拼接图标码位,比如后台上传富文本里直接写了,这种做法绕过了 CSS class,子集化会把它们裁掉。所以执行前先全局搜索&#x和content:的硬编码码位,确认它们都落在提取结果里。
做子集化这类优化时,我养成了一个习惯:把裁完的字体和原字体都留在部署包内,CSS 默认引用子集版,出问题能立刻切回完整版。它算是给老项目的一颗后悔药,省得在深更半夜的线上故障里重新上传字体。希望帮到你。
本文还有配套的精品资源,点击获取