ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Font Awesome 4.7.0 引入与按需瘦身实战:避开图标字体那些坑

Font Awesome 4.7.0 引入与按需瘦身实战:避开图标字体那些坑 简介Font Awesome 4.7.0 是一份面向网页设计师与前端开发者的图标字体库压缩包它将 470 个常用矢量图标封装成 Web 字体让图标可以像文字一样自由缩放、变色并适配各类屏幕避免传统图片图标在响应式设计中的失真与请求开销。包内共 37 个文件整体约 654KB包含 14 个 LESS 与 14 个 SCSS 源码文件、2 个 CSS 样式文件以及 eot、ttf、woff、woff2、svg、otf 六种字体格式兼顾不同浏览器的兼容需要。当前已有 946 人浏览学习适合需要在项目中快速引入图标体系、使用 Sass 或 LESS 定制主题或希望离线部署图标库的开发场景。解压后可直接引用 font-awesome.css 或压缩版也能基于 SCSS/LESS 源文件修改变量和图标样式附带字体文件和帮助文档便于完整接入已有工程是一份稳定且实用的前端资源。1. Font Awesome 4.7.0 是什么一个老图标字体库为何到现在还有人主动装接到老项目打开 HTML 看到满屏fa fa-user、fa fa-cog第一反应是查版本然后搜到一个名字Font Awesome 4.7.0。这个 2016 年发布的图标字体库到今天还有新项目在踩它的坑关键原因是它太能打了一套字体文件加一份 CSS不依赖 JavaScript图标想用就贴个class浏览器兼容性比 5.x、6.x 那套多前缀方案宽得多尤其适配那些仍跑在 IE11 上的老后台系统。这个版本解决的真实问题是在不改造构建流程的前提下给传统多页应用、模板系统、甚至直接改 HTML 的场景快速提供一套视觉统一的图标集。适合谁维护遗留系统的工程师、给政府或企业内部做低代码平台的团队以及所有被安全合规要求拦住升级路线的人。它没有魔法就是一个字体文件的加载问题但加载错了图标就变成一个个方框。2. 引入 Font Awesome 4.7.0三步把字体文件落到本地2.1 先搞懂 4.7.0 的加载原理font-face 与 CSS 伪元素Font Awesome 4.7.0 的本质是自定义字体。它通过font-face声明一个叫FontAwesome的字体家族然后用.fa类配合::before伪元素把图标的 Unicode 码点写进content属性。你在页面上写的i classfa fa-user/i实际渲染过程是浏览器看到.fa-user::before里的content: \f007再从FontAwesome字体里取出对应字形画出来。字体文件按浏览器类型分成多种格式官方 CSS 里的声明顺序有讲究font-face { font-family: FontAwesome; src: url(../fonts/fontawesome-webfont.eot?v4.7.0); src: url(../fonts/fontawesome-webfont.eot?#iefixv4.7.0) format(embedded-opentype), url(../fonts/fontawesome-webfont.woff2?v4.7.0) format(woff2), url(../fonts/fontawesome-webfont.woff?v4.7.0) format(woff), url(../fonts/fontawesome-webfont.ttf?v4.7.0) format(truetype), url(../fonts/fontawesome-webfont.svg?v4.7.0#fontawesomeregular) format(svg); font-weight: normal; font-style: normal; }代码逻辑说明第一行src专供 IE8 及以下识别第二个src按 woff2、woff、ttf、svg 的顺序加载浏览器只认第一个匹配成功的格式现代浏览器会优先取 woff2因为它体积最小、压缩率最好。v4.7.0这个查询参数只用于版本缓存刷新跟字体内容无关。参数说明里最值得留意的是字体路径。CSS 文件在css/目录字体在fonts/目录所以 URL 写../fonts/。如果你把 CSS 和字体放在同一层这里必须改成./fonts/或fonts/否则页面直接显示方框且没有任何报错排查起来非常玄学。2.2 拿到离线资源从 npm 或 CDN 把 4.7.0 下载到本地我一般不会直接在 HTML 里引公共 CDN原因很实际内网环境访问不了外网或者等保要求静态资源必须走本地域。常见的做法是用 npm 把 4.7.0 这个版本包拉下来再把它当普通静态资源处理。# 用 npm 拉取指定版本的离线包不要装成项目依赖只当下载器用 npm pack font-awesome4.7.0 # 解压得到 package 目录里面就是 css、fonts、less 等原始文件 tar -xzf font-awesome-4.7.0.tgz mv package font-awesome-4.7.0如果你不想经过 npm也可以直接从 cdnjs 按文件逐个下载。注意字体文件有五个必须下全mkdir -p fa/css fa/fonts curl -L -o fa/css/font-awesome.min.css \ https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css cd fa/fonts for f in fontawesome-webfont.eot fontawesome-webfont.woff2 \ fontawesome-webfont.woff fontawesome-webfont.ttf fontawesome-webfont.svg; do curl -L -O https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/fonts/$f done参数说明curl -L跟随重定向-O保持原文件名保存。这里强烈建议下载完整压缩包而不是只下font-awesome.min.css因为后续做按需精简时你需要原始的font-awesome.css未压缩版和全部字体格式缺了没法继续操作。下载完成后目录结构大概是这样font-awesome-4.7.0/ ├── css/ │ ├── font-awesome.css │ └── font-awesome.min.css └── fonts/ ├── fontawesome-webfont.eot ├── fontawesome-webfont.svg ├── fontawesome-webfont.ttf ├── fontawesome-webfont.woff └── fontawesome-webfont.woff22.3 最小可运行页面三步把图标显示出来把资源放进项目的static或public目录后页面里只需要三步引入 CSS、写i标签、加aria-hidden。下面是一个完整的最小示例!DOCTYPE html html langzh-CN head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 titleFont Awesome 4.7.0 最小示例/title link relstylesheet hreffa/css/font-awesome.min.css /head body i classfa fa-user aria-hiddentrue/i i classfa fa-cog aria-hiddentrue/i i classfa fa-trash aria-hiddentrue/i /body /html逻辑说明link指定相对路径href相对于当前 HTML 文件所在目录fa是基础类负责把font-family设为FontAwesome并重置伪元素的样式fa-user、fa-cog这些具体图标类只干一件事往::before里写码点。aria-hiddentrue不是可选装饰。纯装饰性图标如果不加屏幕阅读器会尝试朗读字体的私有码点用户听到的是一串乱码。如果你的图标承担了按钮含义比如“删除”按钮里那个垃圾桶应该在外层包一个有aria-label的按钮而不是直接让图标裸奔。如果页面上图标还是没出来先别急着改代码打开浏览器 Network 面板看fontawesome-webfont.woff2请求有没有 404。绝大多数问题不是 CSS 写错而是字体文件路径断在打包或部署那一步。2.4 三种引入方式对比CDN、本地静态资源、npm 构建实际项目里4.7.0 的引入方式绕不开这三种差别主要在环境适配和改造成本上引入方式适用场景优点明显短板公共 CDN快速 demo、个人博客零配置几秒钟出效果内网不可用版本不受控有被投毒和宕机风险本地静态资源老系统、模板渲染、内网部署完全离线路径自己可控每次升级或加图标都要手动替换文件npm 打包工具现代前端工程版本锁定可配合按需裁剪需要 webpack/vite 配置老项目不一定愿意动选型建议老后台系统直接用第二种复制css和fonts两个目录进去就完事。如果项目已经跑在 webpack 或 vite 上优先用npm install font-awesome4.7.0然后通过import font-awesome/css/font-awesome.min.css引入这样打包器会自己处理字体文件的复制和路径重写省掉手工维护。3. 给 Font Awesome 4.7.0 做按需瘦身子集字体与 SVG 方案3.1 为什么要给 4.7.0 做减法全量字体对首屏的拖累Font Awesome 4.7.0 一共收录了 675 个图标但一个页面真正用到的往往不超过 30 个。全量加载意味着用户要下载完整的字体文件这个文件有几十 KB 到上百 KB取决于格式。对于内网后台可能无所谓但对公网页面尤其在移动端弱网环境下字体文件会阻塞图标渲染表现为先出现一片空白或方框字体加载完才一闪而过视觉上非常掉价。另一个容易被忽略的点是浏览器解析 CSS 时会为每个font-face建立字体回退链全量字体如果 woff2 加载失败还会尝试 woff、ttf这种回退策略在低端设备上有额外开销。所以做按需裁剪不只是省流量更是减少浏览器字体加载的失败面。3.2 提取真实使用的图标从项目源码里生成字体子集先收集项目里所有用到的fa-前缀类名。GNU grep 一条命令就能完成# 递归扫描源码和模板提取 fa-* 类名去重后写入文件 grep -rhoE fa-[a-zA-Z0-9-] src/ templates/ | sort -u used-icons.txt参数说明-r递归目录-o只输出匹配部分而不是整行-h不打印文件名-E启用扩展正则。把src/和templates/换成你的实际源码目录模板文件如果是.blade.php、.html、.vue、.jsx都适用。拿到类名清单后再写个小脚本从 CSS 里反查对应的 Unicode 码点并把码点转成真正的 Unicode 字符。这一步是生成字体子集的前提因为字体裁剪工具只认字符不认类名import re # 读取 4.7.0 的未压缩 CSS提取 类名-码点 的映射 css open(font-awesome.css, encodingutf-8).read() mapping dict(re.findall( r\.(fa-[a-zA-Z0-9-]):before\s*\{\s*content:\s*[\]\\f([a-f0-9])[\], css )) used_chars set() missing [] for line in open(used-icons.txt, encodingutf-8): name line.strip() if name in mapping: used_chars.add(chr(int(mapping[name], 16))) else: missing.append(name) # 把去重后的 Unicode 字符写入文本文件供 pyftsubset 读取 with open(icons.txt, w, encodingutf-8) as f: f.write(.join(used_chars)) print(f映射成功 {len(used_chars)} 个图标) if missing: print(未匹配到的类名:, missing)逻辑说明re.findall用分组一次拿回类名和十六进制码点chr(int(mapping[name], 16))把f007这种十六进制数转成对应字符最终icons.txt里就是真实要保留的字符集合。脚本输出未匹配的类名能帮你及时发现拼写错误或把别的图标库的类混进来了。然后用fonttools的pyftsubset命令做裁剪。这个工具是字体处理领域的标准选手不是某个图标的专用脚本# 先安装 fonttools pip install fonttools pyftsubset fontawesome-webfont.ttf \ --text-fileicons.txt \ --output-filefontawesome-subset.woff2 \ --flavorwoff2 \ --layout-features* \ --symbol-cmap \ --legacy-cmap参数说明--text-file从文本文件读取要保留的字符集合这是最贴合项目实际的一种方式--flavorwoff2指定输出格式你也可以生成 woff 或直接输出 ttf--symbol-cmap保留符号字符映射表对 Font Awesome 这种把图标放在 Unicode 私用区的字体是必须的--legacy-cmap兼容老浏览器的字符映射查找方式IE 下能不能显示就看它。3.3 替换精简 CSS只让页面加载一份瘦身后的字体生成新字体后CSS 不用改动图标类名只需要把font-face里的src指向新字体文件。手动改太啰嗦我常用 sed 直接替换一份副本cp css/font-awesome.min.css css/font-awesome.subset.min.css # 把 CSS 中所有 fontawesome-webfont 的引用替换成子集字体 sed -i s#fontawesome-webfont#fontawesome-subset#g css/font-awesome.subset.min.css # 把 fonts 目录也复制一份保持相对路径一致 cp fonts/fontawesome-subset.woff2 fonts/逻辑说明sed的#作为分隔符避免和路径里的/冲突s#old#new#g是全局替换所有字体格式引用不管 eot、woff2 还是 ttf统一指到新文件名的对应格式。如果你的子集只生成了 woff2就把 CSS 里其他src行删掉或者保留一个 ttf 作为兜底。实际部署时把页面里的样式引用从font-awesome.min.css换成font-awesome.subset.min.css字体请求数就从五个格式变成一个流量和浏览器解析时间都降下来。前提是子集字体里确实包含了页面用到的所有图标如果后续有人新增了没在清单里的图标字形会缺所以这个操作应该固化到 CI 或者发布流程里而不是手工执行。3.4 换掉字体几个常用图标直接内联 SVG 的另一种思路除了子集字体还可以在关键路径上彻底绕开字体。常见做法是把 4.7.0 的图标转成 SVG sprite页面只加载一张 SVG 雪碧图用symbol引用某个图标颜色和大小直接用 CSS 控制完全不受字体加载状态影响。转 SVG sprite 的路径打开 fontello.com 的 Import 功能选择 Font Awesome 配置按需勾选项目里用到的图标下载生成包里面已经有fontello.css和svg/fontello.svg。引入方式是在 HTML 里埋入一张隐藏的 SVG 雪碧图svg styledisplay:none xmlnshttp://www.w3.org/2000/svg symbol idicon-user viewBox0 0 1792 1792 path d.../path /symbol /svg svg classiconuse xlink:href#icon-user/use/svg代码说明symbol内部是图标的矢量路径数据use xlink:href#icon-user按id引用。SVG 方案相对于字体有几个实打实的好处不会出现方框、多色图标能实现字体只能单色、样式可以用 CSS 的fill精准控制。但代价是模板里每个图标都要写svguse标签不像fa fa-user那么简洁老系统改造量偏大。如果项目是新的或者要对图标做动效和皮肤切换建议直接上 SVG。如果只是维护存量页面子集字体方案改动最小一行 CSS 都不用重写踩坑面更窄。4. Font Awesome 4.7.0 使用避坑五个踩过的真实坑4.1 图标显示成方框八个里有七个是字体没加载成功现象页面结构正常.fa类也打上了但页面上出现空心方框或一个点。原因最常见是 CSS 加载成功字体文件却 404 了。CSS 里url(../fonts/fontawesome-webfont.woff2)是相对 CSS 文件的路径不是相对当前网页的路径。部署时如果把 CSS 放到了css/目录、字体却放在了其他位置路径就对不上。内网部署尤其容易踩因为 Windows Server 的 IIS 有时还会漏配 woff2 的 MIME 类型直接拒绝对外输出。解决先开 Network 面板看字体请求的完整地址和状态码。如果 404调整font-face里的相对路径如果 403 或 500检查 Web 服务器对字体文件的访问权限。Nginx 下建议显式声明字体扩展名server { # 将字体文件的 MIME 类型固定避免浏览器按默认类型处理导致拒绝渲染 types { font/woff2 woff2; font/woff woff; application/vnd.ms-fontobject eot; font/svg svg; } location ~* \.(eot|otf|ttf|woff|woff2|svg)$ { add_header Access-Control-Allow-Origin *; } }逻辑说明types块里的映射关系会影响Content-Type响应头错误的值会让 Firefox 直接拒绝渲染。Access-Control-Allow-Origin *是应对跨域引用的如果字体只跟 CSS 同域这一行可以不加。4.2 图标错位或者渲染成别的符号别乱改 font-family 名字现象图标是显示出来了但内容明显不对比如fa-user渲染成一本书或者出现国际象棋的马。原因font-face里的font-family: FontAwesome和 CSS 里.fa { font-family: FontAwesome }必须严格一致。有些优化脚本或手工处理时图省事把字体家族改成了别的名字伪元素里content的码点还是原来的但字体映射不上了浏览器会用本地其他字体里的对应码点渲染于是出现随机字形。还有一种是项目里引入了第二个图标字体库两家都声明了FontAwesome这个名字后者覆盖前者码点就和字形库对不上了。解决把font-face的font-family改成一个项目内不会冲突的名字比如FontAwesome47然后全局搜一遍 CSS 里所有font-family: FontAwesome的地方统一改成新名字。如果项目用了多个字体库建议在浏览器里执行document.fonts.check(16px FontAwesome47)确认当前字体是否真的可用返回false就别查 CSS 了先去查覆盖冲突。4.3 升级到 5.x 或 6.x 时图标大面积丢失前缀体系变了现象把 4.7.0 的 CSS 换成了最新版 CDN结果页面上一半图标变成空方块。老代码里fa fa-remove、fa fa-close、fa fa-trash-o这类类名在新版里直接失效。原因5.x/6.x 把单一fa前缀拆成了fas、far、fal、fab四套体系并且移除了 4.7.0 里的部分别名类。官方为了兼容提供了一个v4-shims.css但它只会补常用别名不会覆盖所有旧类名。搜索结果里大量“升级失败”的帖子都是卡在这一步。解决如果你只是想让老页面在新版样式下也能跑先别急着删 4.7.0 的 CSS把新旧两套都引入4.7.0 用独立命名的字体家族名和前缀。真正要迁移就需要做一次类名映射。常用几个对应关系4.7.0 类名5.x / 6.x 对应类名fa fa-trash-ofar fa-trash-altfa fa-remove/fa fa-closefas fa-timesfa fa-floppy-ofar fa-save最稳妥的迁移路径是全局搜索源码中fa fa-开头的字符串输出一份清单对照官方图标页逐个确认而不是用自动化工具直接翻新。4.7.0 里同一个语义对应多个别名fa-remove和fa-times自动替换很容易把没问题的代码改坏。4.4 构建工具把字体类名“摇”掉了动态拼类名导致 purgeCSS 误杀现象开发环境图标正常npm run build后生产环境一排方框看构建产物 CSS 里.fa-user:before整段都消失了。原因Tailwind 或其他 PostCSS 插件配置了内容扫描只保留代码里能以字符串形式出现的类名。像fa- name这种动态拼接的扫描器识别不出fa-user是合法使用直接把它当无用样式清掉了。4.7.0 的整套图标类名都是构建期静态可查的按字符串扫描的工具天然存在这个盲区。解决不用改 Font Awesome改构建配置。Tailwind 里把.fa相关规则加入 safelist或者干脆关掉对静态资源目录的扫描。这条血泪经验的本质是字体图标的 CSS 只有在运行时才能真正确定哪些类有用构建器不该替你做决定。4.5 图标顔色、大小怎么调都没反应查清是谁覆盖了伪元素继承现象给i stylecolor: red; font-size: 24px设置了内联样式图标还是黑色、还是 16px怎么都不听话。原因.fa基础类里设置font-size: inherit且color: inherit图标颜色和大小本应从外层继承。但很多老项目的全局样式里有非常具体的选择器比如table i { font-size: 12px !important }或者第三方 UI 库把i元素当斜体标签重置过。样式优先级一算!important的直接赢了。解决查看浏览器 Elements 面板里计算后的样式看color和font-size是从哪个选择器来的。如果确认是全局残留包一个专门的.fontawesome-icon容器来提权而不是在业务代码里反复写!important.fontawesome-icon, .fontawesome-icon * { font-size: inherit !important; color: inherit !important; line-height: 1 !important; }逻辑说明把!important集中收口到一个辅助类上业务层不需要感知。这个技巧适用于所有被第三方样式污染的字体图标场景。5. 让 Font Awesome 4.7.0 长期好用码点反查、组件封装与团队规范5.1 不打开图标页也能查码点从 CSS 反查 Unicode 的两种姿势周围同事经常问“这个图标到底叫什么”其实不用去翻官网本地 CSS 文件里就有一份完整索引。用 grep 直接查grep -oE \.fa-user:before[^}]* css/font-awesome.css输出大概是{content:\f007}。想确认两个类名是不是同一个图标比如fa-trash和fa-trash-o把两个名字都查一遍对比码点就行。这个操作在排查问题时比翻网页快得多因为网页上列出的名字和 CSS 里实际生效的类名可能有差异后者才是真相。如果你在写内联样式不想为此引入整套 CSS也可以直接用码点.my-badge::before { content: \f007; font-family: FontAwesome; }这里\f007就是fa-user的码点带上font-family声明后无需任何.fa类。这条技巧在改第三方模板时尤其好用你可以在不碰原样式文件的情况下给某个元素补一个图标。5.2 在业务代码里封装图标组件避免散装类名失控老系统里最容易失控的就是图标到处出现在模板的各个角落今天用fa-trash明天同事写了fa-trash-o后天又有人直接内联码点。我建议在业务层收敛成一层映射以 Vue 为例template i :class[fa, cls] aria-hiddentrue/i /template script const MAP { user: fa-user, settings: fa-cog, delete: fa-trash, search: fa-search, close: fa-times, save: fa-floppy-o, add: fa-plus-circle, back: fa-arrow-left, }; export default { name: AppIcon, props: { name: { type: String, required: true }, }, computed: { cls() { return MAP[this.name] || fa- this.name; }, }, }; /script代码说明MAP是业务语义到 4.7.0 类名的映射表是全局唯一入口。业务侧只写app-icon namedelete /组件内部负责翻译成fa-trash。将来如果项目要迁移到 5.x 或换成 SVG sprite只需要改MAP和组件模板页面业务代码一行不用动。return fa- this.name这个兜底再配合构建时代码扫描能提前发现新用到的图标没进映射表。命名规范上我习惯用一张表固定常见操作避免团队各写各的业务含义推荐 4.7.0 类名说明新增 / 创建fa-plus-circle强动作按钮场景优先删除 / 移除fa-trash危险操作建议配合二次确认编辑fa-pencil比fa-edit语义更明确保存 / 提交fa-floppy-o老系统沿用磁盘意象兼容性最好搜索fa-search全局唯一不用fa-binoculars关闭 / 取消fa-times统一用fa-times不用别名fa-remove返回 / 后退fa-arrow-left移动端优先更多fa-ellipsis-v列表和菜单场景通用规范的价值是让代码评审有据可依。别人提交里出现fa-remove或fa-dashboard直接指回这张表比争论“我觉得这个更好看”高效得多。同时把这份表放在 README 里每次新增图标先更新表再开写比事后清理省力。5.3 验证这次改造是否成功三个命令确认字体没有白折腾做完瘦身或引入后我习惯用几个命令快速验证而不是只靠肉眼看页面。先把字体清单列出来确认页面实际引用的不是全量文件# 查看页面引用的字体请求过滤掉其他资源 grep -oE [a-zA-Z0-9.-]\.(woff2?|ttf|eot|svg) index.html css/font-awesome.subset.min.css再通过解析子集字体文件确认字符是否齐全。用 fonttools 反向打印字体包含的字符范围跟used-icons.txt对比python3 - PY from fontTools.ttLib import TTFont font TTFont(fonts/fontawesome-subset.woff2) cmap font.getBestCmap() print(f字数: {len(cmap)}) for cp in sorted(cmap)[:20]: print(hex(cp), cmap[cp]) PY逻辑说明getBestCmap()返回字体里所有字符映射len(cmap)是子集保留的字符数量。如果这个数明显少于图标数说明裁剪生效了。最后一步是真实浏览器验证把.fa元素的computed样式里的content值和font-family打出来确认最终渲染路径确实命中新字体才算闭环。我踩过的最狠的一次教训就是把子集字体做完了但忘记替换 CSS 里的font-face引用结果页面一直加载全量字体瘦身白做。从那以后我把字体子集和 CSS 替换两步写进了同一个 shell 脚本防止下次再犯。这套方法在 Font Awesome 4.7.0 上验证过也适用于任何基于font-face的图标字体库希望帮到你。本文还有配套的精品资源点击获取
返回列表