網站可透過一組用戶端提示標頭,在要求期間選擇性取得使用者的媒體偏好設定,讓伺服器可以基於效能考量而內嵌正確的 CSS。
CSS 媒體查詢,特別是 prefers-color-scheme
或 prefers-reduced-motion
等使用者偏好媒體功能,可能會對需要由網頁提供的 CSS 數量以及使用者載入網頁時體驗的 CSS 產生重大影響。
著重於 prefers-color-scheme
,但強調原因也適用於其他使用者偏好媒體功能,最佳做法是在重要算繪路徑中,針對不相符的色彩配置載入 CSS,改為只載入目前相關的 CSS。其中一種方法是透過 <link media>
。
不過,為了遵循使用者偏好的 Google 搜尋等高流量網站,為了滿足使用者偏好 (例如 prefers-color-scheme
),而內嵌 CSS 出於效能考量,則在要求時需要瞭解偏好的色彩配置 (或其他使用者偏好媒體功能),因此初始 HTML 酬載已內嵌正確的 CSS。
此外,特別是 prefers-color-scheme
的網站。無論如何,網站都應該避免閃爍的色彩主題不正確。
Sec-CH-Prefers-Color-Scheme
和 Sec-CH-Prefers-Reduced-Motion
用戶端提示標頭是一系列使用者偏好設定媒體功能用戶端提示標頭,目標是解決這個問題。
客戶提示背景
HTTP 用戶端提示定義了 Accept-CH
回應標頭,可讓伺服器通告要求標頭以進行主動內容協商,統稱用戶端提示。使用者偏好設定媒體功能用戶端提示標頭提案會定義一組用戶端提示,用來傳達使用者偏好的媒體功能。這些用戶端提示會根據使用者回報的對應使用者偏好設定媒體功能命名。舉例來說,目前依照 prefers-color-scheme
所選擇的偏好色彩配置,會透過名稱對應的 Sec-CH-Prefers-Color-Scheme
用戶端提示回報。
重要客戶提示背景資訊
使用者偏好設定媒體功能用戶端提示標頭中提出的用戶端提示,大概是重要用戶端提示。「重要用戶端提示」是「用戶端提示」,可以大幅改變產生的資源。這類資源應在各網頁載入時 (包括「初始」initial頁面載入) 一致擷取,以免造成使用者看不到的切換按鈕。
用戶端提示語法
使用者偏好設定媒體功能包含名稱 (例如 prefers-reduced-motion
) 和允許的值 (例如 no-preference
或 reduce
)。每個用戶端提示標頭欄位都會以 HTTP 結構化標頭物件表示,其中含有值為「字串」的 項目。例如,如要表示使用者偏好使用深色主題和較小型的動態效果,用戶端提示會如以下範例所示。
GET / HTTP/2
Host: example.com
Sec-CH-Prefers-Color-Scheme: "dark"
Sec-CH-Prefers-Reduced-Motion: "reduce"
在上述用戶端提示中,所傳達資訊的 CSS 分別為 @media (prefers-color-scheme: dark) {}
和 @media (prefers-reduced-motion: reduce) {}
。
完整的用戶端提示清單
用戶端提示清單是根據「媒體查詢層級 5」中的使用者偏好媒體功能建立模型。
用戶端提示 | 接受的值 | 對應的使用者偏好媒體功能 |
---|---|---|
Sec-CH-Prefers-Reduced-Motion |
no-preference 、reduce |
prefers-reduced-motion |
Sec-CH-Prefers-Reduced-Transparency |
no-preference 、reduce |
prefers-reduced-transparency |
Sec-CH-Prefers-Contrast |
no-preference 、less 、more 、custom |
prefers-contrast |
Sec-CH-Forced-Colors |
active 、none |
forced-colors |
Sec-CH-Prefers-Color-Scheme |
light 、dark |
prefers-color-scheme |
Sec-CH-Prefers-Reduced-Data |
no-preference 、reduce |
prefers-reduced-data |
瀏覽器支援
Chromium 93 支援 Sec-CH-Prefers-Color-Scheme
用戶端提示標頭。
Chromium 108 支援 Sec-CH-Prefers-Reduced-Motion
用戶端提示標頭。
其他供應商的意見回饋 (即 WebKit 和 Mozilla) 尚待審查。
Sec-CH-Prefers-Color-Scheme
示範
試用 Chromium 93 中的示範,並留意內嵌 CSS 如何根據使用者偏好的色彩配置而變更。
Sec-CH-Prefers-Reduced-Motion
示範
試用 Chromium 108 中的示範,並留意內嵌 CSS 如何根據使用者的動作偏好設定變更。
運作方式
- 用戶端向伺服器發出初始要求。
bash GET / HTTP/2 Host: example.com
- 伺服器會回應,透過
Accept-CH
告知用戶端其接受Sec-CH-Prefers-Color-Scheme
和Sec-CH-Prefers-Contrast
用戶端提示,而根據Critical-CH
的規定,系統會將Sec-CH-Prefers-Color-Scheme
視為關鍵用戶端提示,並依Vary
所傳達的回應調整。bash HTTP/2 200 OK Content-Type: text/html Accept-CH: Sec-CH-Prefers-Color-Scheme, Sec-CH-Prefers-Contrast Vary: Sec-CH-Prefers-Color-Scheme Critical-CH: Sec-CH-Prefers-Color-Scheme
- 接著,用戶端會重試要求,透過
Sec-CH-Prefers-Color-Scheme
通知伺服器有使用者偏好採用深色配置的內容。bash GET / HTTP/2 Host: example.com Sec-CH-Prefers-Color-Scheme: "dark"
- 伺服器即可根據用戶端的偏好設定調整回應,例如將負責深色主題的 CSS 內嵌至回應內文。
Node.js 範例
下方的 Node.js 範例是針對熱門 Express.js 架構撰寫,顯示了處理 Sec-CH-Prefers-Color-Scheme
用戶端提示標頭的實際執行方式。這個程式碼是上述示範的實際運作來源。
app.get("/", (req, res) => {
// Tell the client the server accepts the `Sec-CH-Prefers-Color-Scheme` client hint…
res.set("Accept-CH", "Sec-CH-Prefers-Color-Scheme");
// …and that the server's response will vary based on its value…
res.set("Vary", "Sec-CH-Prefers-Color-Scheme");
// …and that the server considers this client hint a _critical_ client hint.
res.set("Critical-CH", "Sec-CH-Prefers-Color-Scheme");
// Read the user's preferred color scheme from the headers…
const prefersColorScheme = req.get("sec-ch-prefers-color-scheme");
// …and send the adequate HTML response with the right CSS inlined.
res.send(getHTML(prefersColorScheme));
});
隱私權和安全性考量
Chromium 團隊會依據「控管強大的網路平台功能存取權」中所述的核心原則,設計及實作使用者偏好設定媒體功能用戶端提示標頭,包括使用者控制權、資訊公開和人體工學。
HTTP 用戶端提示的安全性考量,以及用戶端提示的可靠性安全性考量,同樣同樣適用於本提案。
參考資料
- 規格草稿
- 說明
- Sec-CH-Prefers-Color-Scheme - Chrome 狀態項目
- Sec-CH-Prefers-Color-Scheme - Chromium 錯誤
- Sec-CH-Prefers-Reduced-Motion - Chrome 狀態項目
- Sec-CH-Prefers-Reduced-Motion - Chromium 錯誤
- WebKit 執行緒
- Mozilla 標準位置
- 用戶端提示
- 用戶端提示可靠性
- 媒體查詢層級 5
- HTTP 適用的結構化標頭
特別銘謝
非常感謝 Yoav Weiss 提供的寶貴意見和建議。Tdadamemd 在 Wikimedia Commons 上提供的主頁橫幅。