原文鏈接:https://dsx2016.com/?p=1063
公衆號:大師兄2016
css引入自定義字體
使用css3
的@font-face
引入自定義字體
@font-face{
font-family: dsxFont; // 設置自定義字體的名稱
src: url('https://dsx.com/dsxFont.ttf') // 引用字體資源-url或者本地文件
}
使用引入的字體
div{
font-family: dsxFont;
}
不考慮兼容性等問題,這裏有一個不得不留意的地方:中文字體文件太大。
英文由於只有26
個字母,所以不論是哪一種字體,其文件體積也不會大於幾十kb
。
由於漢字的總數約近於十萬個,日常使用3000
字可覆蓋大部分書面場景,但就算是這樣,一個字體的文件也大概有5M
左右。
對於現在的網站訪問來說,有極大的影響,不僅消耗流量,還損失了體驗,得不償失。
fonttools
轉換合併字體文件
python的第三方庫fonttools
可以將指定的內容生成字體文件的子集,同時可以轉換爲指定的文件格式。
對於wordpress
博客而言,我們只需要轉換當前文章內容所使用的字體即可,這樣文件體積會非常小,能夠解決上述痛點。
安裝fonttools
pip install fonttools
使用方法
pyftsubset <字體文件> --text=<需要的字形> --output-file=<輸出文件>
js
引用網絡字體(動態)
在製作插件的時候,考慮可以動態選擇自定義字體。
如果使用完整的字體文件則直接切換指定的css
類即可,但是現在的前提是文章的每種字體文件都是根據文章內容實時變化。
這種情況不僅意味着需要根據當前文章內容實時生成指定的字體文件,且css
也需要動態引用新的字體文件url
。
可以通過js
來動態加載和設置字體集
// 使用網絡字體文件資源實例化字體
let f = new FontFace('dsxFont', 'url(https://dsx.com/dsxFont.ttf)', {});
// 當字體資源加載完畢後
f.load().then(function (loadedFace) {
// 將字體加入當前網頁的自定義字體集
document.fonts.add(loadedFace);
// 然後設置頁面body元素的字體展示優先匹配剛引入的指定字體
document.body.style.fontFamily = 'dsxFont, serif';
});
雖然通過js
可以實現動態加載字體,但是仍然遺留幾個優化問題。
-
不想通過每次存儲字體文件的形式來引用字體。
-
每篇文章內容對應不同字體的數據可以存入
wordpress
數據庫,既能夠減少第三方資源依賴,增加字體訪問速度,還能夠一鍵遷移所有wordpress
數據。
加載arrayBuffer
字體
參考鏈接:
https://developer.mozilla.org/zh-CN/docs/Web/API/FontFace
FontFace()
接口:
既可以使用URL指向的外部資源,也可以使用ArrayBuffer
構造並返回一個新的 FontFace
對象。
後端api
接口可以讀取字體文件返回base64
字符串,js
可以將base64
數據轉爲arrayBuffer
,同時base64
可以存儲在數據庫中。
所以這種方式即不需要文件資源上傳,也可以存入wordpress
數據庫(文章id關聯標識),取出來也可以直接加載爲網頁字體資源。
// 獲取base64數據-通過api接口或者wordpress自己的數據庫
let base64Data=""
//封裝base64轉arrayBuffer函數
let base64ToUint8Array= (base64String) =>{
const padding = '='.repeat((4 - base64String.length % 4) % 4);
const base64 = (base64String + padding)
.replace(/\-/g, '+')
.replace(/_/g, '/');
const rawData = window.atob(base64);
const outputArray = new Uint8Array(rawData.length);
for (let i = 0; i < rawData.length; ++i) {
outputArray[i] = rawData.charCodeAt(i);
}
return outputArray;
};
// 獲取最終的 arrayBufferData
let arrayBufferData=base64ToUint8Array(base64Data);
//實例化字體資源
let f = new FontFace('dsxFont', arrayBufferData, {}); // // 使用arrayBuffer實例化字體-二進制數據緩衝區
// 當字體資源加載完畢後
f.load().then(function (loadedFace) {
// 將字體加入當前網頁的自定義字體集
document.fonts.add(loadedFace);
// 然後設置頁面body元素的字體展示優先匹配剛引入的指定字體
document.body.style.fontFamily = 'dsxFont, serif';
});
python API
讀取文件返回base64
因爲fonttools
爲python
庫,所以api
接口自然也是python
。
生成完精簡的字體文件後,立馬讀取文件並返回base64
數據
# 引入base64模塊
import base64
# 要讀取的文件(字體文件)
path = './font.subset.ttf'
# 讀取文件以二進制流的方式
f = open(path, 'rb')
# 轉化爲base64數據
base64_str = base64.b64encode(f.read())
# 打印在控制檯(記得使用decode解碼爲不帶b的字符串)
print(base64_str.decode())
這裏生成的數據就是前端需要的數據
免費商用字體
使用字體一定要優先注意版權問題。
目前字體種類繁多,版權聲明模糊不清,有的說可以免費商用,有的又說需要授權。
到底是哪一種一定要親自到官網查證,不確定的建議不要使用。
具體可以參考Google Font
:https://fonts.google.com/
也可以參考我之前寫過的文章《9個免費可商用的字體推薦》