網路上的可變字型簡介

新的字型規格,可大幅縮減字型檔案大小

本文將說明變數字型、其優點,以及如何在工作中使用變數字型。首先,我們來複習一下字體排版在網路上的運作方式,以及可變字體帶來的創新。

截至 2020 年 5 月,大多數瀏覽器都支援可變字型。請參閱「可否使用可變字型?」和「備用字型」。

開發人員經常混用「字型」和「字體」這兩個詞彙。不過,兩者還是有差異:字體是基礎視覺設計,可用於許多不同的排版技術;字型則是其中一種實作方式,以數位檔案格式呈現。換句話說,字體樣式是您「看到」的內容,而字型是您「使用」的內容。

另一個經常被忽略的概念是樣式和系列之間的差異。樣式是單一特定字體,例如粗斜體,而系列則是完整的樣式組合。

在可變字型推出之前,每種樣式都會實作為獨立的字型檔案。使用可變字型時,所有樣式都可以包含在單一檔案中。

Roboto 系列的示例組合和不同樣式的清單
左圖:Roboto 字體系列的規格。右側:系列中的命名樣式。

設計人員和開發人員面臨的挑戰

設計師在建立沖印專案時,會面臨一些限制,例如頁面版面配置的實際大小、可使用的顏色數量 (取決於要使用的印刷機類型) 等等。但可使用任意數量的字體樣式。也就是說,平面媒體的排版通常都很豐富且精緻,因此閱讀體驗非常愉悅。回想上次瀏覽精彩雜誌的情況。

網頁設計師和開發人員的限制條件與平面設計師不同,其中一個重要的限制條件是設計相關的頻寬成本。這一直是更豐富的排版體驗的難題,因為這類體驗的成本較高。使用傳統的網路字型時,設計中使用的每種樣式都需要使用者下載個別的字型檔案,這會增加延遲時間和頁面算繪時間。僅包含 Regular 和 Bold 樣式,以及其斜體對應項目,字型資料大小可能就會達到 500 KB 以上。甚至在處理字型的算繪方式、要使用的備用模式,或 FOIT 和 FOUT 等不理想的副作用前,就已發生這種情況。

許多字型系列都提供更廣泛的樣式,包括精簡到黑色、窄版和寬版、各種樣式細節,甚至是特定大小的設計 (適合大型或小型文字)。由於您必須為每種樣式 (或樣式組合) 載入新的字型檔案,因此許多網頁開發人員選擇不使用這些功能,以免降低使用者的閱讀體驗。

可變字型剖析

變數字型會將樣式打包成單一檔案,以解決這些問題。

這項功能會從中性或「預設」樣式開始,通常是「Regular」(一般),這是直立的羅馬設計,具有最典型的粗細和寬度,最適合用於純文字。接著連接至連續範圍中的其他樣式,稱為「軸」。最常見的軸是「粗細」,可將預設樣式連結至粗體樣式。任何個別樣式都可以沿著軸找到,稱為可變字型的「例項」。有些字型例項是由字型開發人員命名,例如重量軸位置 600 稱為 SemiBold。

變數字型 Roboto Flex 的「Weight」軸有三種樣式。一般樣式位於中間,軸線兩端有兩種樣式,一種較輕,另一種較重。您可以選擇下列 900 個執行個體:

以不同粗細顯示的字母「A」
上圖:Roboto 字體的粗細軸解剖圖。

字型開發人員可以提供一組不同的軸。您可以將這些樣式合併,因為它們都使用相同的預設樣式。Roboto 在寬度軸有三種樣式:一般位於軸中央,兩端則有更窄且更寬的樣式。這些屬性會提供 Regular 樣式的所有寬度,並與 Weight 軸結合,提供所有重量的寬度。

Roboto Flex 的寬度和粗細隨機組合

這表示您有數千種樣式!這可能看起來過於誇張,但這種多樣化的字型樣式,可以大幅提升閱讀體驗品質。如果沒有效能懲罰,網頁開發人員可以使用少量或大量樣式,這取決於他們的設計。

斜體

在可變字型中處理斜體的方式很有趣,因為有兩種不同的方法。Helvetica 或 Roboto 等字體具有內插相容輪廓,因此它們的羅馬風格和斜體樣式可以在之間插入,並使用「Slant」軸做為斜體。

其他字型 (例如 Garamond、Baskerville 或 Bodoni) 的羅馬和斜體字元輪廓不支援插補。舉例來說,通常定義羅馬小寫字母「n」的輪廓,與用於定義義大利小寫字母「n」的輪廓不符。「斜體」軸會從羅馬切換為斜體等弧,而不是讓兩個輪廓線互相插入。

字體 Amstelvar 的權重軸範例
Amstelvar 的「n」輪廓,以斜體 (12 點、一般粗細、一般寬度) 和羅馬體顯示。圖片由 Font Bureau 的字型設計師兼排版師 David Berlow 提供。

切換為斜體後,使用者可用的軸應與羅馬字母相同,字元集也應相同。

字符替換功能也適用於個別字符,並可用於可變字型的設計空間中的任何位置。舉例來說,含有兩個垂直條的美元符號設計最適合較大的點陣圖,但在較小的點陣圖中,含有一個條的設計會比較適合。如果我們用於轉譯符號的像素較少,兩條線條的設計可能會變得難以辨識。為解決這個問題,類似斜體軸,在字型設計者決定的點上,沿著Optical Size軸,可發生一個字形替換為另一個字形的情況。

總而言之,輪廓線允許時,類型設計人員就能建立能在多維度設計空間中插入不同樣式的字型。這樣一來,您就能精細控管您的字體排版,並發揮極大效用。

軸定義

有五個註冊軸可控制字型的已知、可預測功能:粗細、寬度、光學大小、傾斜和斜體。除了這些之外,字型也可以包含自訂軸。這些元素可控制類型設計人員想要的字型設計層面:Serif 的大小、洗臉的長度、遞增器高度或 i 上的圓點大小。

雖然軸可以控制相同的特徵,但可能使用不同的值。舉例來說,在 Oswald 和 Hepta Slab 可變字型中,只有一個可用的軸,即粗細,但範圍不同:Oswald 的範圍與升級為可變字型前的範圍相同,即 200 到 700,但 Hepta Slab 的極細粗細為 1,可達到 900。

五個已註冊的軸具有 4 個字元的小寫標記,用於在 CSS 中設定值:

軸名稱和 CSS 值
體重 wght
寬度 wdth
slnt
光學尺寸 opsz
斜體 ital

由於字型開發人員會定義可在可變字型中使用的軸線,以及這些軸線可使用的值,因此必須找出每個字型提供的內容。字型的說明文件應該提供這項資訊,或者您可以使用 Wakamai Fondue 等工具檢查字型。

用途和優勢

設定軸值時,請根據個人喜好和字體排版最佳做法。任何新技術都有可能遭到濫用的風險,而過於藝術或探索性的設定也可能降低實際文字的可讀性。在標題部分,探索不同軸線以創造出精彩的藝術設計很有趣,但如果是內文,則可能會導致文字難以辨識。

令人興奮的表情

Mandy Michael 的草原範例

上方顯示的藝術創作是 Mandy Michael 探索字體 Decovar 的絕佳例子。

如要查看上述範例的有效範例和原始碼,請按這裡

動畫

字型 Zycon 是 Font Bureau 的字型設計師兼排版師 David Berlow 為動畫設計的字型。

此外,您也可以探索使用可變字型的動畫字元。上方範例顯示了 Zycon 字體搭配不同軸線的效果。請參閱 Axis Praxis 上的動畫範例

Anicons是世界上第一個根據質感設計圖示打造的動畫顏色圖示字型。Anicons 是一種實驗,結合了兩種尖端字型技術:可變字型和彩色字型。

幾個 Anicon 彩色圖示字型懸停動畫範例

Finesse

Amstelvar 的 Amstelvar 會相反的 XTRA,使字詞寬度縮小

Roboto FlexAmstelvar 提供一組「參數軸」。在這些軸線上,字母會被解構為 4 個基本形式:黑色或正向形狀、白色或負向形狀,以及 x 和 y 維度。就像原色可以與任何其他顏色混合以進行調整一樣,這 4 個面向可用於微調任何其他軸線。

Amstelvar 中的 XTRA 軸可讓您調整每百萬個單位的「白色」值,如上圖所示。使用 XTRA 的少量字元,在相反方向上,字詞的寬度會平均分配。

CSS 中的變數字型

載入變數字型檔案

變數字型會透過與傳統靜態網頁字型相同的 @font-face 機制載入,但有兩項新的增強功能:

@font-face {
    font-family: 'Roboto Flex';
    src: url('RobotoFlex-VF.woff2') format('woff2-variations');
    src: url('RobotoFlex-VF.woff2') format('woff2') tech('variations');
    font-weight: 100 1000;
    font-stretch: 25% 151%;
}

1. 來源格式:如果瀏覽器不支援可變字型,我們不希望瀏覽器下載字型,因此我們新增 formattech 說明:一次在未來語法 (format('woff2') tech('variations')) 中,一次在已淘汰但在瀏覽器中支援的語法 (format('woff2-variations')) 中。如果瀏覽器支援可變字型且支援即將推出的語法,則會使用第一個宣告。如果可支援可變字型和目前的語法,系統就會使用第二個宣告。兩者都指向相同的字型檔案。

2. 樣式範圍:您會發現我們為 font-weightfont-stretch 提供兩個值。我們現在會提供字型支援的粗細範圍,而非告知瀏覽器這個字型提供的特定粗細 (例如 font-weight: 500;)。如果是 Roboto Flex,權重軸的範圍從 100 到 1000,而且 CSS 會直接將軸範圍對應至 font-weight 樣式屬性。在 @font-face 中指定範圍後,系統會將超出範圍的任何值「上限」為最接近的有效值。寬度軸範圍會以相同方式對應至 font-stretch 屬性。

如果您使用 Google Fonts API,系統會自動處理這項作業。不僅 CSS 包含正確的來源格式和範圍,在不支援變數字型的情況下,Google Fonts 還會傳送靜態備用字型。

使用權重和寬度

目前,您可以從 CSS 中可靠的軸:透過 font-weightwght 軸,wdth 軸則是通過 font-stretch

傳統上,您會將 font-weight 設為關鍵字 (lightbold) 或介於 100 和 900 之間的數值,步進為 100。使用可變字型時,您可以設定字型寬度範圍內的任何值:

.kinda-light {
  font-weight: 125;
}

.super-heavy {
  font-weight: 1000;
}
Roboto Flex 的 Weight 軸從最小值變更為最大值。

同樣地,我們可以透過關鍵字 (condensedultra-expanded) 或百分比值來設定 font-stretch

.kinda-narrow {
  font-stretch: 33.3%;
}

.super-wide {
  font-stretch: 151%;
}
Roboto Flex 的寬度軸已從最小值變更為最大值。

使用斜體和斜體

ital 軸適用於同時包含一般樣式和斜體樣式的字型。軸是開/關切換鈕:值 0 為關閉,會顯示一般樣式,值 1 會顯示斜體。與其他軸不同,這裡沒有轉場效果。0.5 的值不會產生「半斜體」。

slnt 軸與斜體不同,它不是新的樣式,而是將一般樣式傾斜。預設值為 0,代表預設的直立字母形狀。Roboto Flex 的最大傾斜角度為 -10 度,也就是說,字母會從 0 傾斜至 -10。

透過 font-style 屬性設定這些軸會很直覺,但截至 2020 年 4 月,具體做法仍在研擬中。因此,您目前應將這些軸視為自訂軸,並透過 font-variation-settings 設定:

i, em, .italic {
    /* Should be font-style: italic; */
    font-variation-settings: 'ital' 1;
}

.slanted {
    /* Should be font-style: oblique 10deg; */
    font-variation-settings: 'slnt' 10;
}
Roboto Flex 的 Slant 軸從最小值變更為最大值。

使用光學尺寸

字型樣式可以顯示為非常小 (12 像素的註腳) 或非常大 (80 像素的標題)。字型可以回應這些大小變化,藉由變更字母形狀來配合大小。小尺寸的圖片不太適合顯示精細的細節,而大尺寸的圖片則可顯示更多細節和較細的筆觸。

以不同光學尺寸顯示的字母「a」
Roboto Flex 字母「a」的不同像素大小,經過縮放後會顯示出設計上的差異。您也可以在 Codepen 上親自試試

我們為這個軸新增了 CSS 屬性:font-optical-sizing。預設值為 auto,可讓瀏覽器根據 font-size 設定軸值。這表示瀏覽器會自動挑選最佳光纖大小,但如要關閉這項功能,您可以將 font-optical-sizing 設為 none

如果您刻意想要讓光學大小不符合字型大小,也可以為 opsz 軸設定自訂值。下列 CSS 會導致文字以大尺寸顯示,但以 8pt 的光學尺寸顯示,就像是印刷出來的效果:

.small-yet-large {
  font-size: 100px;
  font-variation-settings: 'opsz' 8;
}

使用自訂軸

與註冊軸不同,自訂軸不會對應至現有的 CSS 屬性,因此您必須一律透過 font-variation-settings 設定這些軸。自訂軸的標記一律為大寫,以便與已註冊的軸做出區別。

Roboto Flex 提供幾個自訂軸,其中最重要的是 Grade (GRAD)。Grade 軸很有趣,因為它可以變更字型的粗細,而不變更寬度,因此換行符號不會改變。透過調整等級軸,您可以避免必須調整會影響整體寬度的重量軸,然後再調整會影響整體重量的寬度軸。

Roboto Flex 成績軸從最小值變更為最大值。

GRAD 是自訂軸,在 Roboto Flex 中的範圍為 -200 到 150。我們需要使用 font-variation-settings 解決這個問題:

.grade-light {
    font-variation-settings: `GRAD` -200;
}

.grade-normal {
    font-variation-settings: `GRAD` 0;
}

.grade-heavy {
    font-variation-settings: `GRAD` 150;
}

Google Fonts 中的可變字型

Google Fonts 已擴充目錄,加入可變字型,並定期新增字型。這個介面目前旨在從字型中挑選單一例項:您選取所需變化版本,然後點選「選取此樣式」,系統就會將該變化版本加入 <link> 元素,以便從 Google 字體擷取 CSS 和字型。

如要使用所有可用的軸或值的範圍,您必須手動撰寫 Google Fonts API 的網址。可變字體總覽會列出所有軸和值。

Google 變數字型連結工具也可以提供完整變數字型的最新網址。

字型變化設定繼承

雖然所有已註冊的軸很快就會透過現有的 CSS 屬性獲得支援,但目前您可能需要使用 font-variation-settings 做為備用方案。如果字型有自訂軸,也需使用 font-variation-settings

不過,我們發現「font-variation-settings」有點小問題。系統會自動將您未明確設定的每個屬性重設為預設值。不會沿用先前設定的值!也就是說,下列做法無法如預期般運作:

<span class="slanted grade-light">
    I should be slanted and have a light grade
</span>

首先,瀏覽器會套用 .slanted 類別的 font-variation-settings: 'slnt' 10。然後再套用 .grade-light 類別的 font-variation-settings: 'GRAD' -200。但這麼做會將 slnt 重設為預設的 0!結果會是輕度的文字,但不會傾斜。

幸好,我們可以使用 CSS 變數來解決這個問題:

/* Set the default values */
:root {
    --slnt: 0;
    --GRAD: 0;
}

/* Change value for these elements and their children */
.slanted {
    --slnt: 10;
}

.grade-light {
    --grad: -200;
}

.grade-normal {
    --grad: 0;
}

.grade-heavy {
    --grad: 150;
}

/* Apply whatever value is kept in the CSS variables */
.slanted,
.grade-light,
.grade-normal,
.grade-heavy {
    font-variation-settings: 'slnt' var(--slnt), 'GRAD' var(--GRAD);
}

CSS 變數會串聯,因此如果元素 (或其中一個父項) 將 slnt 設為 10,則即使將 GRAD 設為其他變數,該值也會保留該值。如需這項技巧的詳細說明,請參閱「修正可變字型繼承」。

請注意,CSS 變數的動畫效果無法運作 (這是設計上的考量),因此下列效果無法運作:

@keyframes width-animation {
   from { --wdth: 25; }
   to   { --wdth: 151; }
}

這些動畫必須直接在 font-variation-settings 上執行。

提高廣告成效

OpenType 可變字型可讓我們將字型系列的多種變化版本儲存在單一字型檔案中。Monotype 進行了一項實驗,將 12 個輸入字型組合起來,產生八種粗細,並在斜體和羅馬風格中各自使用三種寬度。在單一可變字型檔案中儲存 48 個個別字型,可減少 88% 的檔案大小

不過,如果您只使用 Roboto Regular 等單一字型,且沒有其他字型,如果改用具有多個軸線的可變字型,可能不會看到字型大小的淨增量。一如既往,這取決於您的用途。

另一方面,在設定之間為字型製作動畫可能會導致效能問題。雖然瀏覽器支援可變字型後,這個問題會有所改善,但如果只為目前在畫面上的字型製作動畫,就能進一步減少這個問題。這個由 Dinamo 提供的實用程式碼片段,可在元素不在畫面上時暫停使用 vf-animation 類別的動畫:

var observer = new IntersectionObserver(function(entries, observer) {
  entries.forEach(function(entry) {
    // Pause/Play the animation
    if (entry.isIntersecting) entry.target.style.animationPlayState = "running"
    else entry.target.style.animationPlayState = "paused"
  });
});

var variableTexts = document.querySelectorAll(".vf-animation");
variableTexts.forEach(function(el) { observer.observe(el); });

如果您的字型會回應使用者互動,建議您節制或去抖動輸入事件。這可防止瀏覽器轉譯可變字型的例項,因為這些例項與先前的例項差異不大,人眼無法察覺差異。

如果您使用 Google 字型,建議您預先連線https://fonts.gstatic.com,也就是 Google 字型代管的網域。這樣一來,瀏覽器在 CSS 中遇到字型時,就能提早知道從何處取得字型:

<link rel="preconnect" href="https://fonts.gstatic.com" />

此提示也適用於其他 CDN:只要讓瀏覽器越早建立網路連線,就能越快下載字型。

如要進一步瞭解載入 Google 字型的最佳做法,請參閱「最快的 Google 字型」。

備用和瀏覽器支援

所有新型瀏覽器都支援可變字體。如果您需要支援舊版瀏覽器,可以選擇使用靜態字型建構網站,並使用可變字型做為漸進式增強功能:

/* Set up Roboto for old browsers, only regular + bold */
@supports not (font-variation-settings: normal) {
  @font-face {
    font-family: Roboto;
    src: url('Roboto-Regular.woff2');
    font-weight: normal;
  }

  @font-face {
    font-family: Roboto;
    src: url('Roboto-Bold.woff2');
    font-weight: bold;
  }

  body {
    font-family: Roboto;
  }

  .super-bold {
    font-weight: bold;
  }
}

/* Set up Roboto for modern browsers, all weights */
@supports (font-variation-settings: normal) {
  @font-face {
    font-family: 'Roboto';
    src: url('RobotoFlex-VF.woff2') format('woff2 supports variations'),
         url('RobotoFlex-VF.woff2') format('woff2-variations');
    font-weight: 100 1000;
    font-stretch: 25% 151%;
  }

  .super-bold {
    font-weight: 1000;
  }
}

對於舊版瀏覽器,具有 .super-bold 類別的文字會以一般粗體顯示,因為這是我們唯一可用的粗體字型。在支援可變字型時,我們可以實際使用 1000 這個最重的粗細。

Internet Explorer 不支援 @supports 規則,因此這個瀏覽器不會顯示任何樣式。如果這是問題所在,您可以隨時使用其中一個老式駭客攻擊來指定相關的舊版瀏覽器。

如果您使用 Google Fonts API,系統會為訪客的瀏覽器載入適當的字型。假設您要求 Oswald 字型的粗細範圍為 200 到 700,如下所示:

<link href="https://fonts.googleapis.com/css2?family=Oswald:wght@200..700&display=swap" rel="stylesheet">

可處理可變字型的新式瀏覽器會取得可變字型,並提供 200 到 700 之間的所有粗細。較舊的瀏覽器會收到每個粗細的個別靜態字型。在這種情況下,這表示他們會下載 6 個字型檔案:一個是粗細 200,另一個是粗細 300,依此類推。

謝謝

本文只能在下列人員的幫助下才得以問世:

主頁橫幅圖片由 Bruno Martins 提供,取自 Unsplash