Chromium 83 中 macOS system-ui 字型提供更多可變字型選項

Catalina 為 macOS 提供全新的統一系統字型。

亞當.亞蓋爾 (Adam Argyle)
Adam Argyle
多米尼克羅茨奇
多米尼克羅茨奇

CSS 字型模組級別 4 規格的 「system-ui」部分定義了 system-ui 字型關鍵字,可讓開發人員在網站和應用程式中使用內建、強化型最佳化、經過大幅最佳化調整、極高品質且無需下載的預設作業系統字型。

body {
  font-family: system-ui;
}

這種字體排版選項類似「使用目前這個使用者目前語言代碼的預設系統字型」。

在 macOS 中,system-ui 字型是舊金山,這是設計團隊審核、測試的字型,最近升級了!首先,我們會介紹 Catalina 新推出的令人期待的可變字型功能,並會介紹幾個 錯誤以及 Chromium 工程師的解決方式

本文假設您已熟悉可變字型。如果沒有,請觀看網路上的可變字型簡介,觀看下方影片。

瀏覽器相容性

在本文撰寫期間,system-ui 支援 Chromium (自 56 年起)、Edge (自 79 年起)、Safari (自 11 以上版本) 和 Firefox (從 43 以上版本) 支援,但支援 -apple-system 關鍵字。如需更新,請參閱「我可以使用變數字型嗎?」一節。

全新功能

自 Chromium 83 版起,網頁開發人員現在可以使用 Catalina 加入系統字型的新功能。system-ui 字型現在提供更多變數設定:光學大小調整和 2 個不重複的粗細調整:

Mojave
h1 {
  font-family: system-ui;
  font-weight: 700;
  font-variation-settings:
    'wght' 750
  ;
}

Catalina
h1 {
  font-family: system-ui;
  font-weight: 700;
  font-variation-settings:
    'wght' 750,
    'opsz' 20,
    'GRAD' 400,
    'YAXS' 400
  ;
}

在 Mojave 中,system-ui 是只有 wght 設定的可變字型。雖然 Catalina 上的 system-ui 是包含 wghtopszGRADYAXS 設定的可變字型,

看來有一些很棒的漸進式增強設計機會!如有需要,可以實際研究系統字型的細微部分。

wght

接受介於 0900 之間的字型粗細,並且適用於所有字元。

/* 0-900 */
font-variation-settings: 'wght' 750;

opsz

光學大小與主角或字母間距類似,但間距是由人類的眼睛所計算,而非數學。19 或以下的值代表文字和內文文案間距,20 以上值則代表間距顯示標題和標題。

/* 19 or 20 */
font-variation-settings: 'opsz' 20;

GRAD

與重量類似,但不需碰觸水平間距。可接受 4001000 之間的值。

/* 400-1000 */
font-variation-settings: 'GRAD' 500;

YAXS

垂直放大字符。可接受 4001000 之間的值。

/* 400-1000 */
font-variation-settings: 'YAXS' 500;

結合選項

加入幾行 CSS 後,我們就能以大膽的字型調整字型設定,或嘗試其他有趣的組合:

font-weight: 700;
font-weight: bold;
font-variation-settings: 'wght' 750, 'YAXS' 600, 'GRAD' 500, 'opsz' 20;

也就如同這樣,macOS 的 Chromium 使用者都能看到你升級的畫面,自訂 750 重量,並加上其他有趣的調整 👍?

遊樂場

點選下方的「Glitch」上的「Remix to Edit」,取得可編輯的 Glitch 副本,接著編輯新的 font-variation-settings 選項,查看字型對字型的影響。請注意,只有 macOS Catalina 裝置才支援這個 Glitch。

macOS 10.15 的系統字型加入了新功能,macOS 10.15 卻在 Chromium 錯誤追蹤工具中記錄了棘手的 system-ui 錯誤。我想知道它們是否彼此相關!?

附錄:system-ui 迴歸

這個故事有另一個錯誤:#1005969。這個問題回報給 macOS 10.15,因為 system-ui 字型間距看起來較窄且容易破壞。

Facebook 群組頁面上兩個段落的比較。左邊是 Chrome,右邊是 Chrome,Chrome 代表空間細微差異,
左側 Chrome (較常追蹤)、右側 Safari (較光學間距)

背景

您是否曾在 macOS 10.14 上發現,當檔案大小增減時,段落或標題的字型「調小」為其他外觀?

在 Mojave (macOS 10.14) 中,system-ui 字型會根據目標字型大小在兩種字型之間切換。當文字在 20px 下方時,macOS 會使用「舊金山文字」。當文字為 20px 以上時,macOS 會使用「舊金山螢幕」。光學大小是以靜態方式建構成兩個不同字型。

Catalina (macOS 10.15) 為舊金山推出新的統一變數字型。不必再管理「文字」和「多媒體」。此外,它也採用了前述的新版變化版本設定 opsz

h1 {
  font-variation-settings: 'opsz' 20;
}

很抱歉,新 Catalina 字型預設的 opsz 值為 20,且 Chromium 工程師尚未準備將 opsz 套用至系統字型。以免尺寸較小。

為解決這個問題,Chromium 必須正確將 opsz 套用至系統字型。這導致問題 #1005969 有所修正。成功!還是...?

尚未完成

遇到這種情況:Chromium 套用了「opsz」,但某些功能無法正常運作。Mac 上的系統字型還有一個名為 trak 的字型表格,可調整水平間距。修正問題時,Chromium 工程師發現在 macOS 中,從 CTFontRef 物件擷取水平指標時,trak 指標已經在指標結果中列入考量。Chromium 的形狀程式庫 HarfBuzz 需要 trak 值尚未納入的指標。

顯示系統 UI 及其所有字型粗細和變化版本。其中一半沒有體重差異。
左:已將粗體粗細套用到 19 以下版本的字型大小。右:字型大小 20 以上將會失去粗體樣式

Skia (圖形程式庫,而非相同名稱的字體) 會在內部同時使用 CoreGraphicsCGFontRef 類別和 CoreTextCTFontRef 類別。由於這些物件之間必須進行內部轉換 (用來維持回溯相容性及存取兩個類別所需的 API),因此在某些情況下,Skia 會遺失權重資訊,粗體字型將停止運作。我們已在問題 #1057654 中追蹤這個問題。

Chromium 仍支援 macOS 10.11,因此 Skia 仍需支援。10.11 版本中,「San Francisco Text」及「San Francisco Display」字型原先不是可變字型。相反地,每種字型都是由各種可用字型組成的不同字型系列。有時,其字符 ID 會彼此無法同步。因此,如果 Skia 使用「San Francisco Text」繪製文字形狀 (將文字轉換為可繪製的字符),而使用「San Francisco 螢幕」時,文字會呈現胡言亂語,反之亦然。即使 Skia 剛剛要求選擇不同尺寸的 macOS 系統也可能會切換至另一個大小。建議您一律使用其中一種字型,僅使用其中一種字型縮放 (使用矩陣放大,而非要求放大大尺寸),但 CoreText 會發生問題,無法縮放 sbix (顏色表情符號) 字符 (僅向下)。這部分較複雜實際上,CoreText 似乎在矩陣套用範圍後限制了垂直範圍,這似乎與無法在 45 度角繪製表情符號有關。在任何情況下,如果你想顯示大型表情符號,則必須複製字型來取得該字型。

因此,為了在內部建立不同大小的 CTFont 物件副本,同時確保使用相同基礎字型資料,Chromium 已從 CTFont 提取 CGFont,然後從 CGFont 建立新的 CTFont (CGFont 物件的大小各自獨立,但會神奇切換功能是在 CoreText 層級進行)。在 10.154 之前,此功能都能正常運作。10.15 年,這項來回行程最後失去過多資訊,因此造成體重問題。Flutter 發現權重問題,另外一項修正方式是直接透過原始 CTFont 建立新的 CTFont,同時直接在 CoreText 中使用未記錄的舊屬性控制光學大小。這樣即可讓作業 10.11 持續運作,並修正其他問題 (例如明確將光學尺寸設為預設值)。

不過,這樣做會保留字型中更多 CoreText「magic」。其中一個似乎是,該字仍在經過 trak 表格之外以某種方式調整字符 (這是 Chromium 原本嘗試透過未記錄的其他屬性隱藏的適用項目)。

CGFont 並沒有什麼「魔法」,也許 Chromium 可以拿掉 CTFontCGFont,只用來搶佔先機?不過,由於 CoreText 也可使用其他方式混用字型,因此無法使用這個方法。舉例來說,它會使小型表情符號的尺寸比你預期的還要大 (放大一點)。CGFont 不知道這件事,所以您最終的 Ssbix 表情符號之間的距離太近了,因為您會測量一種尺寸,但是 CoreText 會繪製較大的表情符號。Chromium 期待 CTFont 發展進步,但希望在不進行追蹤的情況下取得,而且最好能夠安心無虞。

由於修正間距問題需要一組互連的 Blink 和 Skia 修正,因此 Chromium 工程師無法「只還原」就能修正問題。Chromium 工程師也嘗試使用不同的建構旗標,變更 Skia 中的字型相關程式碼路徑。這雖然修正了大字體的問題,但也修正了空格問題。

修正方法

最終,Chromium 也想修正這兩個問題。現在可以使用 HarfBuzz 內建的 OpenType 字型指標函式,直接從系統字型表格中的二進位資料擷取水平指標。如此一來,當字型有 trak 表格時,Chromium 就會側移 CoreText 和 Skia (表情符號字型除外)。

顯示系統 UI 及其所有字型粗細和變化版本。先前無法發揮作用的一半,現在看起來還不錯。

與此同時,還有Skia 問題 #10123 來追蹤 Skia 的完整修正方式,並改回使用 Skia 從該頁面擷取系統字型指標,而非透過 HarfBuzz 目前的修正。