prefers-reduced-motion 媒體查詢會偵測使用者是否要求作業系統盡量減少動畫或動態的使用量。
並非所有人都喜歡裝飾性動畫或轉場效果,有些使用者在看到視差捲動、縮放效果等時,會直接感到暈眩。使用者偏好媒體查詢 prefers-reduced-motion
可讓您為已表示此偏好的使用者設計減少動態的網站變化版本。
現實生活和網路上的動作過多
前幾天,我和孩子一起溜冰。那天天氣晴朗,陽光普照,溜冰場上擠滿了人 ⛸。唯一的問題是:我無法很好地應付人群。由於有太多移動的目標,我無法專注於任何事物,最後迷失了,並有視覺超載的感覺,就像盯著螞蟻窩 🐜? 一樣。
有時,網路上也會出現類似情況:閃爍的廣告、炫麗的視差效果、令人驚豔的揭露動畫、自動播放的影片等等,網路有時會讓人感到相當吃力。不過,與現實生活不同的是,網路上有解決方案。CSS 媒體查詢 prefers-reduced-motion
可讓開發人員為偏好減少動畫的使用者建立網頁變化版本。這包括避免自動播放影片、停用特定純裝飾效果,以及為特定使用者重新設計網頁等。
在深入探討這項功能之前,讓我們先退一步,想想網頁上會使用哪些動畫。如有需要,您也可以略過背景資訊,直接跳到技術詳細資料。
網路上的動畫
動畫通常用於向使用者提供意見回饋,例如讓他們知道系統已收到並正在處理某項操作。舉例來說,在購物網站上,產品可以透過動畫「飛」進虛擬購物車,並在網站右上角以圖示呈現。
另一種用途是使用動態效果操控使用者的感知,方法是混合使用骨架畫面、內容相關中繼資料和低品質圖片預覽畫面,佔用使用者大量時間,讓整體體驗「感覺上」更快速。這項功能的用意是向使用者提供即將發生的內容,同時盡可能快速載入內容。
最後,還有裝飾性效果,例如動畫漸層、視差捲動、背景影片等。雖然許多使用者都喜歡這類動畫,但有些使用者不喜歡,因為他們覺得動畫會讓他們分心或降低速度。在最糟的情況下,使用者甚至可能會因動態暈而感到不適,就像在現實生活中一樣,因此對這類使用者來說,減少動畫是醫療必要性。
運動觸發的前庭系統障礙
部分使用者會因為動畫內容而分心或感到噁心。舉例來說,如果捲動動畫與捲動相關聯的主元素以外的元素移動幅度過大,就可能導致前庭系統失調。舉例來說,視差捲動動畫會導致前庭系統失調,因為背景元素的移動速度與前景元素不同。前庭 (內耳) 失調反應包括頭暈、噁心和偏頭痛,有時需要臥床休息才能復原。
在作業系統上移除動態
許多作業系統都有無障礙設定,可指定長時間減少動畫的偏好設定。下列螢幕截圖顯示 macOS Mojave 的「Reduce motion」偏好設定,以及 Android Pie 的「Remove animations」偏好設定。勾選後,這些偏好設定會導致作業系統不使用裝飾效果,例如應用程式啟動動畫。應用程式本身也可以且應遵循這項設定,並移除所有不必要的動畫。
移除網頁上的動態內容
Media Queries Level 5 也為網路帶來減少動畫的使用者偏好設定。媒體查詢可讓作者不受正在轉譯的文件影響,測試及查詢使用者代理程式或顯示裝置的值或功能。媒體查詢 prefers-reduced-motion
可用於偵測使用者是否已設定作業系統偏好設定,以便將使用的動畫或動作數量降到最低。這個屬性可接受兩種值:
no-preference
:表示使用者在基礎作業系統中未設定任何偏好設定。這個關鍵字值在布林值上下文中會評估為false
。reduce
:表示使用者已設定作業系統偏好設定,指出介面應盡量減少移動或動畫,最好是移除所有非必要的移動。
使用 CSS 和 JavaScript 上下文中的媒體查詢
如同所有媒體查詢,您可以從 CSS 上下文和 JavaScript 上下文檢查 prefers-reduced-motion
。
舉例來說,假設我有一個重要的訂閱按鈕,希望使用者按下。我可以定義引人注目的「震動」動畫,但身為優質的網頁使用者,我只會向明確同意動畫的使用者播放動畫,而非所有使用者,包括已停用動畫的使用者,或是瀏覽器不支援媒體查詢的使用者。
/*
If the user has expressed their preference for
reduced motion, then don't use animations on buttons.
*/
@media (prefers-reduced-motion: reduce) {
button {
animation: none;
}
}
/*
If the browser understands the media query and the user
explicitly hasn't set a preference, then use animations on buttons.
*/
@media (prefers-reduced-motion: no-preference) {
button {
/* `vibrate` keyframes are defined elsewhere */
animation: vibrate 0.3s linear infinite both;
}
}
為說明如何使用 JavaScript 搭配 prefers-reduced-motion
,假設我已使用 Web Animations API 定義複雜的動畫。雖然瀏覽器會在使用者偏好設定變更時動態觸發 CSS 規則,但對於 JavaScript 動畫,我必須自行監聽變更,然後手動停止可能正在執行的動畫 (或在使用者允許的情況下重新啟動):
const mediaQuery = window.matchMedia('(prefers-reduced-motion: reduce)');
mediaQuery.addEventListener('change', () => {
console.log(mediaQuery.media, mediaQuery.matches);
// Stop JavaScript-based animations.
});
請注意,實際媒體查詢的括號是必要的:
window.matchMedia('prefers-reduced-motion: reduce');
window.matchMedia('(prefers-reduced-motion: reduce)');
透過 <picture>
內容使用媒體查詢
一個有趣的用途是讓播放動畫 AVIF、WebP 或 GIF 取決於 media
屬性。如果 (prefers-reduced-motion: no-preference)
評估為 true
,則可安全地顯示動畫版本,否則顯示靜態版本:
<picture>
<!-- Animated versions. -->
<source
srcset="nyancat.avifs"
type="image/avif"
media="(prefers-reduced-motion: no-preference)"
/>
<source
srcset="nyancat.gif"
type="image/gif"
media="(prefers-reduced-motion: no-preference)"
/>
<!-- Static versions. -->
<img src="nyancat.png" alt="Nyan cat" width="250" height="250" />
</picture>
請參考以下範例。試著切換裝置的動作偏好設定,看看有何不同。
在要求時發現使用者的偏好設定
Sec-CH-Prefers-Reduced-Motion
用戶端提示標頭可讓網站在要求時選擇取得使用者的動畫偏好設定,讓伺服器可基於效能考量內嵌正確的 CSS。
示範
我根據 Rogério Vicente 的 🐈? HTTP 狀態貓咪製作了一個小型示範。首先,請花點時間欣賞這個笑話,它很有趣,我會等待。歡迎回來,讓我介紹示範。捲動時,每個 HTTP 狀態分類都會交替顯示在右側或左側。這項動畫的播放速度為 60 FPS,流暢無比,但如前文所述,有些使用者可能不喜歡這類動畫,甚至會因其產生暈車感,因此我們在製作這項示範時,已將 prefers-reduced-motion
納入考量。這項功能甚至可動態運作,讓使用者可即時變更偏好設定,無須重新載入。如果使用者偏好減少動態效果,系統會移除不必要的揭露動畫,只保留一般捲動動畫。以下螢幕側錄顯示示範內容:
結論
尊重使用者偏好是現代網站的關鍵,而瀏覽器也提供越來越多功能,讓網頁開發人員能這麼做。另一個推出的例子是 prefers-color-scheme
,可偵測使用者偏好淺色或深色色彩配置。你可以在我的文章「Hello Darkness, My Old Friend」中瞭解 prefers-color-scheme
的所有資訊 🌒?。
CSS 工作群組正在將更多使用者偏好媒體查詢標準化,例如 prefers-reduced-transparency
(偵測使用者是否偏好降低透明度)、prefers-contrast
(偵測使用者是否要求系統增加或減少相鄰顏色之間的對比度),以及 inverted-colors
(偵測使用者是否偏好反轉顏色)。
(額外功能) 強制在所有網站上啟用減少動態效果
並非所有網站都會使用 prefers-reduced-motion
,或是可能不符合您的喜好。無論出於何種原因,你都可以停止所有網站上的動態內容。其中一種方法是將含有下列 CSS 的樣式表插入您造訪的每個網頁中。市面上有許多瀏覽器擴充功能可用於這項操作 (使用時請自行承擔風險)。
@media (prefers-reduced-motion: reduce) {
*,
::before,
::after {
animation-delay: -1ms !important;
animation-duration: 1ms !important;
animation-iteration-count: 1 !important;
background-attachment: initial !important;
scroll-behavior: auto !important;
transition-duration: 1ms !important;
transition-delay: -1ms !important;
}
}
運作方式是先前的 CSS 會將所有動畫和轉場的時間長度覆寫為極短的時間,以致於使用者無法察覺。由於部分網站需要執行動畫才能正常運作 (可能是因為某個步驟依賴 animationend
事件的觸發動作),因此較激進的 animation: none !important;
方法將無法運作。即使先前的駭客攻擊可在所有網站上成功執行 (例如,它無法停止使用 Web Animations API 啟動的動作),但如果您發現有問題,請務必停用這項功能。
相關連結
- Media Queries Level 5 規格書的最新編輯者草稿。
prefers-reduced-motion
在 Chrome 平台狀態。prefers-reduced-motion
Chromium 錯誤。- 閃爍意圖實作發布。
特別銘謝
感謝 Stephen McGruer 在 Chrome 中實作 prefers-reduced-motion
,並與 Rob Dodson 共同審查這份文件。主頁橫幅:Unsplash 上的 Hannah Cauhepe 提供。