偏好減少動態:有時候,動作越少

prefers-reduced-motion 媒體查詢會偵測使用者是否要求作業系統盡量減少動畫或動態效果的使用量。

不是每個人都喜歡裝飾性動畫或轉場效果;有些使用者面對視差捲動、縮放效果等效果,會對動態感到暈眩。使用者偏好媒體查詢 prefers-reduced-motion 可讓您為已表示此偏好的使用者設計減少動態的網站變化版本。

瀏覽器支援

  • Chrome:74。
  • Edge:79。
  • Firefox:63。
  • Safari:10.1.

資料來源

現實生活和網路中的動作過多

前幾天,我和孩子一起溜冰。那天天氣晴朗,陽光普照,溜冰場上擠滿了人 ⛸。唯一的問題是:我無法很好地應付人群。由於有太多移動的目標,我無法專注於任何事物,最後迷失了,並有視覺超載的感覺,就像盯著螞蟻窩 🐜 一樣。

許多人滑冰的腳。
現實生活中的視覺超載。

有時,網路上也會出現類似情況:閃爍的廣告、炫麗的視差效果、令人驚豔的揭露動畫、自動播放的影片等等,網路有時會讓人感到相當疲憊。不過,與現實生活不同的是,網路上有解決方案。CSS 媒體查詢 prefers-reduced-motion 可讓開發人員為偏好減少動態效果的使用者建立頁面變化版本。包括不自動播放影片、停用某些純粹裝飾效果,或針對特定使用者徹底重新設計頁面等。

在深入探討這項功能之前,讓我們先退一步,想想網頁上會使用哪些動畫。如有需要,您也可以略過背景資訊,直接跳到技術詳細資料

網頁版動畫

動畫通常用於向使用者提供意見回饋,例如讓他們知道系統已收到並正在處理某項操作。舉例來說,在購物網站上,產品可以動畫成「飛」成虛擬購物車,呈現網站右上角的圖示。

另一個用途是使用動態效果操控使用者的感知,方法是混合使用骨架畫面、內容相關中繼資料和低品質圖片預覽畫面,佔用使用者大量時間,讓整體體驗「感覺上」更快速。這項功能的用意是向使用者提供即將發生的內容,同時盡可能快速載入內容。

最後,還有多種「裝飾」效果,例如動畫漸層、視差捲動、背景影片和其他多種效果。雖然許多使用者都喜歡這類動畫,但有些使用者不喜歡,因為他們覺得動畫會讓他們分心或降低速度。在最糟的情況下,使用者甚至可能會因動態暈而感到不適,就像在現實生活中一樣,因此對這類使用者來說,減少動畫是醫療必要性

運動觸發的前庭系統障礙

部分使用者會因為動畫內容而分心或感到噁心。舉例來說,如果捲動動畫與捲動相關聯的主元素以外的元素移動幅度過大,就可能導致前庭系統失調。舉例來說,視差捲動動畫會導致前庭系統失調,因為背景元素的移動速度與前景元素不同。前庭 (內耳) 失調反應包括頭暈、噁心和偏頭痛,有時需要臥床休息才能復原。

在作業系統上移除動態

許多作業系統都有無障礙設定,可指定長時間減少動畫的偏好設定。以下螢幕截圖顯示 macOS Mojave 的「Reduce action」偏好設定,以及 Android Pie 的「RemoveAnimation」偏好設定。勾選後,這些偏好設定會導致作業系統不使用裝飾效果,例如應用程式啟動動畫。應用程式本身也可以且應遵循這項設定,並移除所有不必要的動畫。

macOS 設定畫面,勾選「減少動態」核取方塊。
Android 設定畫面上的「移除動畫」核取方塊已勾選。

移除網頁上的動態內容

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> 情境中的媒體查詢

其中一個有趣的用途是播放依附於 media 屬性的 AVIF、WebP 或 GIF 動畫。如果 (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-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 啟動的動作),但如果您發現有問題,請務必停用這項功能。

特別銘謝

感謝 Stephen McGruer 在 Chrome 中實作 prefers-reduced-motion,並與 Rob Dodson 共同審查這份文件。主頁橫幅:Unsplash 上的 Hannah Cauhepe 提供。