網路上的可變字型簡介

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

本文將介紹可變字型、這些字型的優點,以及如何在工作中使用這類字型。首先,我們來複習一下網路上的字體排版運作方式 以及可變動字型的創新字型

瀏覽器相容性

自 2020 年 5 月起,大部分瀏覽器都支援可變字型。請參閱「可以使用可變字型嗎?」和「備用項」。

簡介

開發人員經常交替使用「字型」和「字體」這兩個詞彙。 但兩者之間存在差異:字體是基礎視覺設計,可存在於多種不同的輸入技術中,字型是上述實作方式之一,且為數位檔案格式。換句話說,字體就是您「看到」的內容,字型則是「使用」的字型。

另一個經常被忽略的概念是樣式和家庭之間的區別。樣式是單一且特定的字體 (例如粗體斜體),而係列是完整的樣式組合。

在可變字型之前,每種樣式都會以個別的字型檔案的形式實作。透過變數字型,所有樣式都能納入單一檔案中。

Roboto 系列不同樣式的標識與清單
左:Roboto 字體系列的樣本。右圖:系列內的具名樣式。

設計人員與開發人員遇到的難題

設計人員在建立列印專案時面臨一些限制,例如網頁版面配置的實體大小、可使用的顏色數量 (取決於使用的列印點擊種類) 等等。但可以使用任意數量的字體樣式。這表示印刷媒體的字體排版通常豐富且精密,因此可以帶給使用者歡快的閱讀體驗。回想上次瀏覽優質雜誌的情況,

網頁設計人員和開發人員的限制與列印設計人員不同,其中重要的是設計相關的頻寬成本。這是為了提供更豐富多元的字體排版體驗,而這已是誘因,因為它們會導致成本高昂。以傳統網路字型來說,我們在設計中使用的每種樣式都需要使用者下載個別的字型檔案,因此這會增加延遲時間並縮短頁面轉譯時間。只有包含「一般」和「粗體」樣式,以及斜體計數器,大小可達 500 KB 或以上。但我們尚未處理字型的轉譯方式、需要使用的備用模式,或 FOIT 和 FOUT 等不理想的副作用。

許多字型系列的樣式五花八門,包括細、黑色、窄和寬、各種樣式細節,甚至是特定大小的設計 (適合大或小型文字)。由於您必須為每個樣式 (或樣式組合) 載入新的字型檔案,因此許多網頁開發人員選擇不使用這些功能,因而降低了使用者的閱讀體驗。

可變字型圖解

變數字型可將樣式封裝成單一檔案,因應這些挑戰。

其運作方式是從中央或「預設」樣式開始,通常為「一般」,一種是自然的羅馬風格,並且最適合純文字的粗細和寬度。這些樣式會與連續範圍內的其他樣式連結,稱為「軸」。最常見的軸是「Weight」(權重),可連結預設樣式與粗體樣式。任何個別樣式都能位於軸上,稱為變數字型的「執行個體」。部分執行個體是由字型開發人員命名,例如,權重軸位置 600 稱為 SemiBold。

變數字型 Roboto Flex 的「Weight」軸有三種樣式。一般樣式位於中心,軸的對面兩端有兩種樣式,一種較淺,另一個則較大。在這些執行個體中,您可以選擇 900 個執行個體:

以不同粗細顯示的字母「A」
上方:插圖是 Roboto 字體重量軸的剖析圖。

字型開發人員可以提供一組不同的軸。這些元件都會共用相同的預設樣式,因此可以合併。Roboto 在寬度軸上有三種樣式:一般是位於軸的中心,且每個端點都有兩條更窄、較寬的樣式。這些物件會提供一般樣式的所有寬度,並結合權重軸,提供每個粗細的所有寬度。

隨機組合寬度與權重的 Roboto Flex

這表示本來已有數千種風格!這看起來似乎有大量不當的影響,但只要使用多樣化的風格,閱讀體驗的品質就能大幅提升。如果不對效能造成負面影響,網頁開發人員可以視需要使用幾種或任意數量的樣式,一切視其設計而定。

斜體

而變數字型的處理方式是有趣的方式,因為有以下兩種差異。Helvetica 或 Roboto 等字體具有與內插的等邊,因此可以在與Slant 軸之間內插

其他字體 (例如 Garamond、Baskerville 或 Bodoni) 具有與內插不相容的羅馬及斜體字符輪廓。舉例來說,一般定義羅馬小寫「n」的輪廓與用來定義斜體小寫「n」的輪廓不會相符。「斜體」軸會從羅馬到斜體輪廓,不會插入其中一個輪廓。

字體 Amstelvar 的體重軸範例
Amstelvar 的「n」輪廓是斜體 (12 點,一般粗細、正常寬度),以及羅馬字母。圖片由 David Berlow,以及字型局的類型設計人員和字體排版工具提供。

切換到斜體後,使用者可用的軸應與羅馬字母的軸相同,就像字元集一樣。

您也可以查看個別字符的字符替換功能,並在可變字型的設計空間中的任何位置使用。舉例來說,在較大點尺寸中,含有兩個垂直長條的美元符號設計效果最佳,但在小點尺寸中,只使用一個長條會比較好。如果我們能夠算繪字符的像素較少,可能會導致兩個長條的設計變得難以辨識。要對抗這種問題,與斜軸相似,在類型設計人員決定的某個點時,一個字符會替換一個字符可以搭配「光學尺寸」軸發生。

總結來說,在輪廓允許的情況下,類型設計人員可以建立字型,在多維度設計空間中插入各種樣式。還可以精確控製字體排版,而且效能強大。

軸定義

有五種登錄的軸可控製字型的已知及預測特徵:粗細、寬度、光學大小、斜體和斜體。除此之外,字型也可以包含自訂軸。這些控制項可控制類型設計人員想要的字型任何設計方面,包括 Serif 尺寸、沖洗長度、遞增器高度或 i 上的圓點大小。

雖然軸可以控制相同的地圖項目,但也可能使用不同的值。舉例來說,在 Oswald 和 Hepta Slab 中,只有一種軸可用,「Weight」(範圍) 是不同的,但範圍其實與之前的 Oswald 一樣,因此 200 至 700 的高度範圍相同,但 Hepta Slab 的髮線粗細為 1,最高為 900。

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

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

由於字型開發人員會定義變數字型提供哪些軸線,以及可以擁有的值,因此務必瞭解每個字型提供的項目。字型的說明文件應提供這項資訊,或者您可以使用 Wakamai Fondue 等工具檢查字型。

應用實例和優點

設定軸值會依個人品味,並採用字體排版最佳做法。新技術可能會造成誤用,如果設定過於藝術或探索性,也可能導致實際文字的易讀性降低。對於標題,嘗試探索不同的軸線打造出色的藝術設計,實在令人興奮,但對於內文文案,這可能會導致文字難以閱讀。

表現亮眼表現

Mandy Michael 的草地範例

上文是 Mandy Michael 探索字體 Decovar 的優良範例。

您可以在這裡查看上述範例的有效範例和原始碼。

動畫

Typeface Zycon 是由 David Berlow 所設計的動畫作品,以及字型設計人員的字型設計師和字體排版工具。

您也可以探索包含可變字型的動畫字元。以上例子是與 Zycon 字體排版的不同軸。請參閱 Axis Praxis 上的即時動畫範例

Anicons 是世界上第一個以 Material Design 圖示為基礎的動畫顏色圖示字型,「圖示」這項實驗結合了兩種頂尖字型技術:可變字型和顏色字型。

小圖示顏色圖示字型的懸停動畫範例

未婚夫

Amstelvar 會反方向使用 XTRA 微位元,讓字詞的寬度均勻

Roboto FlexAmstelvar 提供一組「Parametric Axes」。在這些軸中,字母會解構為 4 種基本形式:黑色或正面形狀、白色或負形狀,以及 x 和 y 維度。就像讓主要顏色與其他其他顏色混合並進行調整一樣,這 4 個面向可以用來微調任何其他軸。

Amstelvar 中的 XTRA 軸可讓您調整每千分之一的「white」值,如上所示。使用少量的 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,這一切就不會受到影響。如果變數字型不受支援,Google Fonts 不僅會包含正確的來源格式和範圍,也會傳送靜態備用字型。

使用權重和寬度

目前可確實從 CSS 設定的軸是wght軸是 font-weight 軸,wdth 軸則是 font-stretch

一般來說,您可以將 font-weight 設為關鍵字 (lightbold) 或介於 100 到 900 之間的數值 (如第 100 步)。透過可變字型,您可以設定字型寬度範圍內的任何值:

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

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

同樣地,我們可以使用關鍵字 (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 軸已從最小化到最大值。

使用光學大小

字體可以非常小 (12px 註腳) 或非常大 (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)。成績軸很有趣,因為會在不變更寬度的情況下變更字型粗細,因此換行符號不會改變。您可以利用成績軸來玩遊戲,這樣一來,當權重軸發生變更時會影響整體寬度,就可以避免受到強制約束,然後再變更會影響整體權重的寬度軸。

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 Fonts 擷取 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 個個別字型,可減少檔案大小

不過,如果您使用 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 Fonts,建議您預先連結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,系統會為訪客的瀏覽器載入正確字型。假設您要求使用粗細範圍 200 到 700 的字型 Oswald,如下所示:

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

能夠處理可變字型的新型瀏覽器將取得變數字型,且每種粗細的 200 到 700 之間。舊版瀏覽器會針對每種粗細,提供個別的靜態字型。在這個範例中,他們會下載 6 個字型檔案:一個用於權重 200,一個用於權重 300,以此類推。

感謝

本文只會在下列人員的幫助下達成:

主頁橫幅由 Bruno Martins 撰寫,在 Unsplash 網站上。