當在 svg 檔中需要有文字,而文字的字型卻是客製的時候,會發生在 svg 中的文字無法吃到 @font-face 設定的字型,本文紀錄解決方法。
原因
使用 <img>
載入 svg 檔時,它會將檔案以 Base64 編碼,因此你看到的 src
值會像下面這樣:
1 | <img src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iOTNweCIgaGVpZ2h0PSI0OHB4IiB2aWV3Qm94PSIwIDAgOTMgNDgiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8IS0tIEdlbmVyYXRvcjogU2tldGNoIDUxLjEgKDU3NTAxKSAtIGh0dHA6Ly93d3cuYm9oZW1pYW5jb2RpbmcuY29tL3NrZXRjaCAtLT4KICAgIDx0aXRsZT5idG4vbWFpbi9jYW5jZWwvbm9ybWFsPC90aXRsZT4KICAgIDxkZXNjPkNyZWF0ZWQgd2l0aCBTa2V0Y2guPC9kZXNjPgogICAgPGRlZnM+PC9kZWZzPgogICAgPGcgaWQ9ImJ0bi9tYWluL2NhbmNlbC9ub3JtYWwiIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPgogICAgICAgIDxyZWN0IGlkPSJSZWN0YW5nbGUtMyIgZmlsbC1ydWxlPSJub256ZXJvIiB4PSIwIiB5PSIwIiB3aWR0aD0iOTMiIGhlaWdodD0iNDgiPjwvcmVjdD4KICAgICAgICA8dGV4dCBpZD0iQ0FOQ0VMIiBmb250LWZhbWlseT0iUm9ib3RvIiBmb250LXNpemU9IjE2IiBmb250LXdlaWdodD0iYm9sZCIgZmlsbD0iIzc4Nzg3OCI+CiAgICAgICAgICAgIDx0c3BhbiB4PSIxNi4xNjc5Njg4IiB5PSIyNyI+Q0FOQ0VMPC90c3Bhbj4KICAgICAgICA8L3RleHQ+CiAgICA8L2c+Cjwvc3ZnPgo="> |
這樣的做法圖的確會出來,但因為已經轉換為 Base64 了,這個 svg 已經不再是 html 的 tag 所組成,因此在 @font-face
定義的客製字型自然也就吃不到了。
解決方法
解決問題的辦法就是不要將其編碼,用原來的 svg 程式碼加到 html 中,這樣的載入方式稱為 inline ,程式碼如下面所示:
1 | <svg width="93px" height="48px" viewBox="0 0 93 48" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> |
這樣就可以吃到客製的 Roboto
字型了。
解法的難處
這樣的解法雖然解決了字型的問題,但在實作上會十分麻煩,需要將 svg 檔的程式碼複製然後貼至對應的 html 位置,而且使用多次的圖片會在程式碼中被重複貼上,造成維護上的困難。
更好的解決方法
vue-svg-inline-loader
vue-svg-inline-loader 提供了將載入的 svg 置換為 inline 形式的功能:
- Install
vue-svg-inline-loader
1 | npm install vue-svg-inline-loader --save-dev |
- Add Webpack Config
1 | { |
- Add
svg-inline
directive to img tag
1 | <img svg-inline src="./assets/img/normal.svg"> |
vue-svg-loader
vue-svg-loader 提供了將載入的 svg 用 vue component 的形式載入,底子裡還是把 svg 的 html 賦予給 component。
- Install
vue-svg-loader
1 | npm i -D vue-svg-loader |
- Add Webpack Config
1 | { |
- Import svg component
1 | <template> |
這兩個方式都可以達成目的又減輕開發的負擔。