隨着當前 Web 技術的日新月異,網頁界面內容越來越豐富,讓人眼花繚亂,其中就包括了網頁中的各種自定義字體。
例如,個人博客的首頁字體:
CSS3 引入的 @font-face
這一屬性可以很好的解決這個問題,可以幫助我們非常靈活的使用一些特殊的字體,即使用戶電腦里面沒有安裝這個字體,網頁也可以顯示。
EOT
字體是 IE 瀏覽器的首選格式,其他瀏覽器都不支持;其他瀏覽器更鍾愛常見的 TTF
、SVG
、WOFF
。
基本語法如下:
@font-face {
font-family: <自定義一個字體的名稱>;
src: url('<下載好的字體,在電腦中保存的路徑>');
font-variant: <font-variant>;
font-stretch: <font-stretch>;
font-style: <style>;
font-weight: <weight>;
例如:
@font-face {
font-family: 'Lora';
src: url('../fonts/STKaiti.eot'); /* IE9 Compat Modes */
src: url('../fonts/STKaiti.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('../fonts/STKaiti.woff2') format('woff2'), /* Super Modern Browsers */
url('../fonts/STKaiti.woff') format('woff'), /* Modern Browsers */
url('../fonts/STKaiti.ttf') format('truetype'), /* Safari, Android, iOS */
url('../fonts/STKaiti.svg#STKaiti') format('svg'); /* Legacy iOS */
font-style: normal;
font-weight: normal;
}
body {
font-family: STKaiti;
...
}
測試效果:Chrome,Firefox,IE7-IE11 均可以實現
1. 字體難題
自定義中文字體雖炫酷,但有一個弊端,那就是中文字體太大了,很耗費資源,具體的原因其實很簡單:英文只有 26 個字母,一張 ASCII 碼表上 128 個字符集幾乎可以表示任何英文語句。由於字符集小,字體文件也可以做的非常小;中文字體就完全不同,單單 GB2313
編碼的中文字符(含符號)就達到 7445 個,字符數量是 ASCII
碼表的 58 倍,而字體設計師需要為每一個中文字符設計字體,簡單計算下,中文字體文件大小也幾乎達到英文字體文件的數十倍。
2. 解決思路
解決思路其實也很簡單,只在字庫中保留頁面中出現的文字,將其他大量不用的文字刪掉,生成一個只包含特定字符的小字體文件,便可以大大減少字體文件,從而提高訪問速度。現在思路有了,那么有沒有現成的工具呢?
3. 裁剪工具
還真有。經過我一番搜尋,找到了兩款工具:一個是華人開發的「字蛛」,英文名 font-spider
,依賴 Node.js 環境,是一款命令行工具。主要思路是采集線上網頁使用到的字體,從字體文件中分離出來,完成大幅度壓縮。另一個是騰訊的大佬改版后的 font-soider,叫 font-spider-plus。它們的工作原理如下:
我選擇使用 font-spider-plus,畢竟改版過的,bug 更少,功能更多,還支持線上動態渲染的頁面。唯一的不足就是官方文檔寫的太含糊了,許多人看了根本不知道怎么用。下面我將給我一個詳細的范例,手把手教你如何使用 font-spider-plus。
4. font-spider-plus 使用方法
根據官方文檔,要想使用 font-spider-plus,首先要在 CSS
文件中通過 @font-face
引入全量大小的特殊字體。具體怎么做呢?並沒有說,我來告訴你。
書寫 HTML 文件
首先我們新建一個文件夾用來放 html 文件:
$ mkdir index
然后在 index 目錄中創建一個 index.html
文件,內容如下:
<div class="test">
米開朗基楊
</div>
<style>
@font-face {
font-family: 'font';
src: url('../fonts/<font>.eot');
src:
url('../fonts/<font>.eot?#font-spider') format('embedded-opentype'),
url('../fonts/<font>.woff2') format('woff2'),
url('../fonts/<font>.woff') format('woff'),
url('../fonts/<font>.ttf') format('truetype'),
url('../fonts/<font>.svg') format('svg');
font-weight: normal;
font-style: normal;
}
.test{
font-family: 'font';
}
</style>
- 請將
<div class="test"> </div>
中的文字換成你自己的網站的文字。你可以選擇將你的博客所有文章內容全選,然后粘貼到此處。 - 下載你想使用的字體到
fonts
文件夾,然后將 index.html 中的<font>
換成你下載的字體的前綴。
特別說明:
@font-face
中的src
定義的 .ttf 文件必須存在,其余的格式將由工具自動生成
下面是中文字體對應的英文名稱:
新細明體:PMingLiU
細明體:MingLiU
標楷體:DFKai-SB
黑體:SimHei
宋體:SimSun
新宋體:NSimSun
仿宋:FangSong
楷體:KaiTi
仿宋_GB2312:FangSong_GB2312
楷體_GB2312:KaiTi_GB2312
微軟正黑體:Microsoft JhengHei
微軟雅黑體:Microsoft YaHei
裝Office會多出來的一些字體:
隸書:LiSu
幼圓:YouYuan
華文細黑:STXihei
華文楷體:STKaiti
華文宋體:STSong
華文中宋:STZhongsong
華文仿宋:STFangsong
方正舒體:FZShuTi
方正姚體:FZYaoti
華文彩雲:STCaiyun
華文琥珀:STHupo
華文隸書:STLiti
華文行楷:STXingkai
華文新魏:STXinwei
蘋果電腦中的字體:
華文細黑:STHeiti Light [STXihei]
華文黑體:STHeiti
華文楷體:STKaiti
華文宋體:STSong
華文仿宋:STFangsong
麗黑 Pro:LiHei Pro Medium
麗宋 Pro:LiSong Pro Light
標楷體:BiauKai
蘋果麗中黑:Apple LiGothic Medium
蘋果麗細宋:Apple LiSung Light
壓縮本地 WebFont
然后執行下面的命令來壓縮本地 WebFont:
$ fsp local index/index.html
哦對了,你需要先通過 npm 安裝 fsp 命令:
$ npm i font-spider-plus -g
壓縮完成后,就會在 fonts 目錄下生成壓縮后的字體文件:
$ ll fonts/
total 41328
-rw-rw-rw- 1 cnsgyg staff 7.7K 11 21 01:08 STKaiti.eot
-rw-rw-rw- 1 cnsgyg staff 8.2K 11 21 01:08 STKaiti.svg
-rw-rw-rw- 1 cnsgyg staff 7.6K 11 21 01:08 STKaiti.ttf
-rw-rw-rw- 1 cnsgyg staff 7.7K 11 21 01:08 STKaiti.woff
-rw-rw-rw- 1 cnsgyg staff 3.9K 11 21 01:08 STKaiti.woff2
壓縮之前的字體文件會被移到 fonts
目錄下的 .font-spider
目錄:
$ ll fonts/.font-spider
total 24880
-rw-rw-rw- 1 cnsgyg staff 12M 11 21 01:08 STKaiti.ttf
書寫 CSS
現在字體壓縮完了,怎么應用到自己的網站中呢?也很簡單,先寫個 CSS 通過 @font-faxe
引入壓縮后的字體,格式與第一步中的 index.html 類似:
/* fonts-zh.css */
@font-face {
font-family: 'font';
src: url('../fonts/<font>.eot');
src: url('../fonts/<font>.eot?#font-spider') format('embedded-opentype'),
url('../fonts/<font>.woff2') format('woff2'),
url('../fonts/<font>.woff') format('woff'),
url('../fonts/<font>.ttf') format('truetype'),
url('../fonts/<font>.svg') format('svg');
font-weight: normal;
font-style: normal;
}
這樣還不行,你還需要將壓縮后的字體文件拷貝你的網站中,CSS 中通過相對路徑要能找到這些字體文件。可我不想這么做,太麻煩了,我還想更簡單點。
base64 編碼
靈機一動,想到了 base64,編碼之后可以不用拷貝這些字體文件,還能減少網站字體的加載體積,真是一箭雙雕啊!具體的步驟我就不解釋了,直接把所有步驟放到腳本中:
#!/bin/bash
font=STKaiti
eot=$(cat fonts/$font.eot|base64|tr -d '\n')
woff=$(cat fonts/$font.woff|base64|tr -d '\n')
woff2=$(cat fonts/$font.woff2|base64|tr -d '\n')
ttf=$(cat fonts/$font.ttf|base64|tr -d '\n')
svg=$(cat fonts/$font.svg|base64|tr -d '\n')
cat > fonts-zh.css <<EOF
@font-face {
font-family: '$font';
src: url(data:application/font-eot;charset=utf-8;base64,$eot) format('eot');
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: '$font';
src: url(data:application/font-woff2;charset=utf-8;base64,$woff2) format('woff2'),
url(data:application/font-woff;charset=utf-8;base64,$woff) format('woff'),
url(data:application/font-ttf;charset=utf-8;base64,$ttf) format('truetype'),
url(data:application/font-svg;charset=utf-8;base64,$svg) format('svg');
font-weight: normal;
font-style: normal;
}
EOF
執行完上面的腳本后,就生成了一個 fonts-zh.css
,這是我們唯一需要的東西,不再需要任何額外的文件。
引入 CSS
最后一步就是在你的網站中引入該 CSS,具體的做法大同小異,以 hugo 為例,先將 fonts-zh.css
復制到網站主題目錄的 static/css/
目錄下,然后在 <head></head>
中引入該 css,以 beatifulhugo 主題為例,直接在 layouts/partials/head_custom.html
中加上下面一行:
<link rel="stylesheet" href="{{ "css/fonts-zh.css" | absURL }}" />
最后讓網站的 body 使用該中文字體,具體的做法是修改 body 的 css,以 hugo 的 beatifulhugo 主題為例,修改 static/css/main.css
中的 body 屬性:
body {
font-family: STKaiti;
...
}
可以再加上備用字體,例如:
body {
font-family: STKaiti,Cambria;
...
}
表示如果 STKaiti
字體不可用,將使用 Cambria
字體。到這里就大功告成了,具體的效果可以參考我的網站:https://fuckcloudnative.io/。
5. 總結
如果你沒有強迫症,到這一步就大功告成了,可我還覺得不夠簡單,那么多步驟實在是太繁瑣了,我要讓它們全部自動化,把所有的步驟放到一個自動化腳本中。這還不夠,為了造福大眾,我在 GitHUb 中新建了一個倉庫,所有的腳本和步驟都在上面,有需求的小伙伴可以拿去 happy 啦~~
項目地址:https://github.com/yangchuansheng/font-spider-plus
6. 參考資料
微信公眾號
掃一掃下面的二維碼關注微信公眾號,在公眾號中回復◉加群◉即可加入我們的雲原生交流群,和孫宏亮、張館長、陽明等大佬一起探討雲原生技術