真正瞭解 CSS3 背景下的 @font face 規則

zhangxinxu發表於2017-04-01

很多人只要一提到@font face規則,心中就會不由自主“哦~~”的一聲:“這個我知道,可以用來生成自定義字元小圖示!”話是沒錯,問題在於很多人就以為生成字元小圖示就是@font face規則的全部,實際上只是功能之一,如果真正瞭解@font face規則,你會發現,@font face規則可以做的事情其實非常多,尤其我們不考慮IE7,IE8瀏覽器的情況下。

一、 @font face的本質是變數

雖然說CSS3新世界才出現真正意義上的變數var(參見此文:“瞭解CSS/CSS3原生變數var”),但實際上,CSS世界中,就已經出現了本質上就是變數的東西,@font face規則就是其中之一,@font face的本質上就是一個定義字型或字型集的變數,這個變數不僅僅是簡單的自定義字型,還包括字型重新命名,預設字型樣式設定等等。

這個“變數”的意識很重要,有助於我們發揮@font face的潛力,可以讓我們的CSS程式碼更加的精簡,更方便的維護等。

在進入正題之前,我們先要對@font face規則有個大致的面面觀。

@font face規則支援的CSS屬性有:font-familysrcfont-weightfont-styleunicode-rangefont-variantfont-stretchfont-feature-settings。例如:

@font-face {
  font-family: 'example';
  src: url(example.ttf);
  font-style: normal;
  font-weight: normal;
  unicode-range: U+0025-00FF;
  font-variant: small-caps;
  font-stretch: expanded;
  font-feature-settings:"liga1" on;
}

屬性還是挺多的,而且有些屬性,估計是他認識你,你不認識他。但是從實用角度來講,有些屬性其實可以不用去深究,例如font-variantfont-stretchfont-feature-settings3個屬性。為什麼呢?因為按照我的經驗理解,這3個屬性給我感覺更像是專為英文設計的,所以如果不是有業務需要,可以先放一放。

好,現在,是不是感覺壓力一下子小了很多,我們需要在意的可以自定義的屬性就只剩下下面這些:

@font-face {
  font-family: 'example';
  src: url(example.ttf);
  font-style: normal;
  font-weight: normal;
  unicode-range: U+0025-00FF;
}

估計會有小夥伴疑惑@font-face規則中的font-stylefont-weight以及unicode-range這些屬性有什麼用,尤其font-stylefont-weight,好像就是專門過來打醬油的。實際上,這裡的每個屬性都不是泛泛之輩,都是有故事的人。

在介紹每個屬性之前,有必要鄭重宣告一下,接下來有大量的案例,全是基於local本地字型做示意的,而IE7,IE8瀏覽器是不支援local本地字型的,所以,本文的標題是“CSS3背景下的……”,就是這麼個原因,大家注意明辨,如果你的專案還需要相容IE8,本文介紹,這些好東西可能就需要斟酌斟酌了。

二、 @font face常用CSS屬性詳細介紹

我們一個一個來介紹:

1.font-family

這裡的font-family可以看成是一個字型變數,名稱可以非常隨意,例如直接一個美元符號'$',例如:

@font-face {
  font-family: '$';
  src: local("Microsoft Yahei");
}

這時候,對普通HTML元素,你設定其font-family屬性值為'$',則其字型表現就變成了“微軟雅黑”(如果本地有這個字型)。

甚至非IE瀏覽器下可以直接使用純空格' ',不過有一點需要注意,就是使用這些稀奇古怪的字元或者有空格的時候,一定要加引號。

雖然說自己變數名可以很隨意,但是有一類名稱,不能隨便設定,就是原本系統就有的字型名稱,例如下面的程式碼:

@font-face {
  font-family: 'Microsoft Yahei';
  src: local(SimSun);
}

從此“微軟雅黑”字型就變成了“宋體”。當然,有時候我們說不定就需要這種覆蓋,比如說新來了一個設計主管,平生最看不慣“微軟雅黑”,希望換成其他字型,這個時候我們就可以使用這個變數覆蓋輕輕鬆鬆完成整站的字型變更。

2.src

src表示呼叫字型檔案,非是本地字型檔案(IE9+支援),也可以是線上地址(可能有跨域限制)。

本文主要著重介紹本地字型檔案的應用。

作用1:字型檔名簡寫

現在很多網站會使用“微軟雅黑”字型,但是,“微軟雅黑”的名稱有點長:

.font {
    font-family: 'Microsoft Yahei';
}

小手一抖,說不定就拼錯了,還要加引號,還要加空格,好麻煩的勒。此時我們就可以利用@font face規則簡化,這樣就容易記憶了,書寫更快了:

@font-face {
  font-family: YH;
  src: local("Microsoft Yahei");
}

使用的時候直接:

.font {
    font-family: YH;
}

多麼乾淨,多麼清爽,心情多麼舒暢!

src還支援多個local字型地址同時出現,嘿,這簡化的CSS程式碼可不是一個字型名了,而是一大波字型名稱了,例如某網站使用了大量類似下面的font-family屬性值:

body {
    font-family: PingFangSC-Regular,HelveticaNeue-Light,'Helvetica Neue Light','Microsoft YaHei',sans-serif;
}
.xxxx {
    font-family: PingFangSC-Regular,HelveticaNeue-Light,'Helvetica Neue Light','Microsoft YaHei',sans-serif;
}

雖然說,實現的時候,藉助了Sass, Less之類工具讓字型名稱們成為了變數,寫程式碼的時候好像也沒怎麼吃力,但是最終生成的CSS其實是比較囉嗦,如果我們走本質上就是變數的@font face,是不是不僅開發簡單,程式碼也簡單了,如下處理:

@font-face {
  font-family: BASE;
  src: local("HelveticaNeue-Light"), local("Helvetica Neue Light"),  local("PingFang SC"), local("Microsoft YaHei"), local(sans-serif);
}

於是我們用字型的時候直接:

body {
    font-family: BASE;
}
.xxxx {
    font-family: BASE;
}

看語義又好,程式碼又簡單,實用又方便,超級使用的小技巧。

當然,local本地作用還不止這些。

業界有個名為“字蛛”的中文字型處理工具,可以提取頁面中使用的特殊中文字型並生成新的體積更小的自定義字型。我們可以在這個基礎上更進一步,舉個例子:

一些特殊的標題設計師就是喜歡用“方正粗雅宋”這個字型(已經購得版權),但是很顯然,這麼帥氣的字型,幾乎很少有使用者安裝的,所以實際開發的時候,全都是通過工具而生成一個全新的精簡版的“方正粗雅宋”字型檔案,再通過src屬性url()方法外鏈這個字型檔案。

很棒的方案,但還不夠完美,為什麼呢?雖然安裝“方正粗雅宋”這個字型的使用者並不多,但並不表示沒有使用者使用之。試想一下,假如有使用者安裝了這個字型,結果你在網頁呈現的時候,還要再去外鏈一個額外的檔案地址,豈不是白白的浪費?既浪費流量,體驗又不一定好,如果字型檔案載入慢,會看到文字“變形”的過程,顯然是不友好的。

我們可以藉助@font face規則中的local實現程式碼和體驗上的進一步的提升,如下:

@font-face {
  font-family: FZCYS;
  src: local("FZYaSongS-B-GB"), 
       url("FZCYS.woff2"),  
       url("FZCYS.woff"),
       url("FZCYS.ttf");
}

於是乎,那些安裝了“方正粗雅宋”這個字型的使用者,就沒有任何字型檔案請求。載入更快了,使用者體驗上升了,還省了流量,如此百益無一害的事情,還不妥妥的用起來。

3.font-style

在Chrome瀏覽器下,@font face規則設定font-style:italic可以讓文字傾斜,但是這並不是其作用所在。

@font face規則中的font-stylefont-weight類似,都是用來設定對應字型樣式或自重下該使用什麼字型。因為有些字型可能會有專門的斜體字,注意這個斜體字,並不是讓文字的形狀傾斜,而是專門設計的傾斜的字型,很多細節會跟物理上的請求不一樣。於是,我在CSS程式碼中使用font-style:italic的時候,就會呼叫這個對應字型,如下示意:

@font-face {
  font-family: 'I';
  font-style: normal;
  src: local('FZYaoti');
}
@font-face {
  font-family: 'I';
  font-style: italic;
  src: local('FZShuTi');
}

由於專門的斜體字不太好找,所以我使用“方正姚體”和“方正舒體”代替做示意。上面CSS程式碼我解讀一下:制定一個字型,名叫'I',當文字樣式正常的時候,字型表現使用“方正姚體”,當文字設定了font-style:italic的時候,字型表現為“方正舒體”。

好,現在假設有下面這樣的CSS和HTML:

.i {
  font-family: I;
}
<p><i class="i">類名是i,標籤是i</i></p>
<p><span class="i">類名是i, 標籤是span</span></p>

請問最終的表現是怎樣的?

由於<i>標籤天然font-style:italic,因此理論上,上面一行文字表現為“方正舒體”,下面一行為“方正姚體”,最終結果是如何呢?

噹噹噹當,完全符合,如下截圖:

@font-face和font-style關係作用示意

這下大家應該明白,@font face規則中的font-style是幹嘛用的了吧。

4.font-weight

font-weightfont-style類似,不過是定義了不同字重使用不同字型,對於中午而言,這個要比font-style適用性強很多。我這裡就有一個非常具有代表性的例子,版權字型“漢儀旗黑”自重非常豐富,但是這個字型不像“思源黑體”,天然可以根據font-weight屬性值載入對應的字型檔案,怎麼辦呢?很簡單,使用@font face規則重新定義一下即可,例如下面的CSS程式碼:

@font-face {
  font-family: 'QH';
  font-weight: 400;
  src: local('HYQihei 40S');
}
@font-face {
  font-family: 'QH';
  font-weight: 500;
  src: local('HYQihei 50S');
}
@font-face {
  font-family: 'QH';
  font-weight: 600;
  src: local('HYQihei 60S');
}

解讀一下就是,是一個全新的字型,名為'QH',當字重font-weight400的時候,使用“漢儀旗黑 40S”字重字型,為500的時候,使用“漢儀旗黑 50S”字重字型,為600的時候,使用“漢儀旗黑 60S”字重字型。

於是乎,當我們應用如下的CSS和HTML程式碼的時候:

.hy-40s,
.hy-50s,
.hy-60s {
  font-family: 'QH';
}
.hy-40s {
  font-weight: 400;
}
.hy-50s {
  font-weight: 500;
}
.hy-60s {
  font-weight: 600;
}
<ul>
  <li class="hy-40s">漢儀旗黑40s</li>
  <li class="hy-50s">漢儀旗黑50s</li>
  <li class="hy-60s">漢儀旗黑60s</li>
</ul>

我們就可以看到,文字粗細錯落有致的效果,如下截圖:

@font-face中font-weight作用示意截圖

如果用在網頁開發中,必定會讓我們的介面更加的細膩,設計更加的精緻,視覺更加的愉悅。

5.unicode-range

unicode-range的作用是可以讓特定的字元或者字元片段使用特定的字型。舉個例子,下圖是文字應用了“微軟雅黑”字型後的效果:

微軟雅黑的冒號

但是,這兩個“引號”左右間隙不均,方向不明,實在是看著不爽,此時我們就專門指定這兩個“引號”使用其他字型,如下CSS:

@font-face {
  font-family: BASE;
  src: local("Microsoft Yahei");
}
@font-face {
  font-family: quote;
  src: local('SimSun');    
  unicode-range: U+201c, U+201d;
}
.font {
    font-family: quote, BASE;
}

然後效果就變成這樣子了:

變成宋體引號後的效果

嗯,一下子變得舒服多了。

關於unicode-range更多內容,可參考我之前寫的文章“CSS unicode-range特定字元使用font-face自定義字型”。

三、結束語

根據我個人的感覺,@font-face的為人所知要得益於icon fonts小圖示技術。因為自定義的小圖示字型幾乎一定是外鏈的,而恰恰好,低版本IE7,IE8瀏覽器的src只能是url()外部字型檔案。外加向量、顏色可控等特性,於是成為了相容時代最好的小圖示解決方案,可謂功不可沒,但也帶來了另外一個弊端,讓很多同學誤以為@font-face除了自定義一些小圖示之外就一無是處了。於是,當越來越多產品和專案不需要相容IE7,IE8瀏覽器的時候,由於有更好的SVG圖示解決方案,@font-face似乎又很少被提及了。

通過本文的一些介紹,大家應該感覺到@font-face規則的作用被嚴重低估了,除了小圖示外,@font-face還能做的事情非常多,而這些事情,才更像是@font-face應該做的事情。

就算你的專案需要相容IE8,本文介紹的一些特性也是可以漸進增強使用的,例如特殊中文字型優先使用本地字型,或者unicode-range特定字元使用特定字型等。

希望本文的內容可以喚起大家對@font-face真正的認識!

感謝閱讀,歡迎交流!

相關文章