Preferreds-reduced-motion: 動きが少ないほうがよい場合もあります

Preferreds-reduced-motion メディアクエリは、ユーザーがオペレーティング システムに対して、使用するアニメーションやモーションの量を最小限に抑えるようリクエストしたかどうかを検出します。

装飾的なアニメーションや遷移が誰もが好むわけではなく、視差スクロールやズーム効果などに直面すると、非常に不快なユーザーもいます。ユーザー設定のメディアクエリ prefers-reduced-motion を使用すると、その設定を行ったユーザーのために、モーションを低減したサイトのバリエーションをデザインできます。

対応ブラウザ

  • 74
  • 79
  • 63
  • 10.1

ソース

現実世界やウェブ上での動きが多すぎます

先日、子どもたちとアイススケートをしていました。晴れの日で、スケートリンクは人でいっぱいだったよ ⛸ 唯一の問題は、人混みにうまく対応できないということ。動く標的があまりに多いので、何も集中できず、道に迷って、 アリの山 🐜? をじっと眺めているような感覚に陥ります。

アイススケートをしている人たちの群れ。
現実世界での視覚的な過負荷。

ウェブでも、点滅する広告、華やかな視差効果、驚くべき明快なアニメーション、動画の自動再生などにより、ウェブが圧倒されるようなことがあります... 幸いなことに、現実の生活とは異なり、その解決策があります。CSS メディアクエリ prefers-reduced-motion を使用すると、動きの軽減を好むユーザー向けにページのパターンを作成できます。これには、動画の自動再生を控えることから、特定の純粋な装飾効果を無効にすること、特定のユーザーのためにページを完全に再設計することなどが含まれます。

この機能の詳細に入る前に、ウェブでどのようなアニメーションが使用されるかについて考えてみましょう。必要に応じて背景情報はスキップし、以下の技術情報の詳細に進むこともできます。

ウェブでのアニメーション

アニメーションは、ユーザーにフィードバックを提供する場合などによく使用されます。たとえば、アクションが受信され、処理中であることをユーザーに知らせることができます。たとえば、ショッピング ウェブサイトでは、商品をアニメーションで操作して仮想ショッピング カートにジャンプし、サイトの右上にあるアイコンにすることができます。

別のユースケースとしては、スケルトン画面、コンテキスト メタデータ、低品質の画像プレビューを組み合わせて使用し、ユーザー エクスペリエンス全体をより速く感じさせることで、モーションを使用してユーザーの認識をハッキングするというユースケースがあります。これは、今後の流れについてユーザーにコンテキストを提供し、同時に読み込みを可能な限り迅速に行うためです。

最後に、アニメーション グラデーション、パララックス スクロール、バックグラウンド動画など、装飾的な効果があります。多くのユーザーはこのようなアニメーションを楽しんでいますが、気が散ったり遅くなったりするため、気に入らないユーザーもいます。最悪のケースでは、あたかも現実に起きているかのように乗り物酔いに苦しむことさえあります。そのため、このようなユーザーにとってアニメーションを減らすことは医療上の必要性です。

運動誘発性前庭スペクトル障害

一部のユーザーは、アニメーション コンテンツからの注意散漫や吐き気を経験します。たとえば、スクロールに関連するメイン要素以外の要素が多く動き回ると、スクロール アニメーションで前庭の障害が発生することがあります。たとえば、視差スクロール アニメーションは、背景要素が前景要素とは異なる速度で動くため、前庭の障害を引き起こすことがあります。前庭(内耳)障害の反応には、めまい、吐き気、片頭痛などがあり、回復するために寝床が必要となる場合もあります。

オペレーティング システムのモーションの削除

多くのオペレーティング システムには、以前から動きの軽減を優先するユーザー補助設定がありました。以下のスクリーンショットは、macOS Mojave の [モーションの軽減] 設定と Android Pie の [アニメーションを無効化] 設定を示しています。これらの設定をオンにすると、オペレーティング システムはアプリの起動アニメーションなどの装飾効果を使用しません。アプリ自体もこの設定を使用し、不要なアニメーションをすべて削除できます。

[モーションを減らす] チェックボックスがオンになっている macOS の設定画面のスクリーンショット。
[アニメーションを無効化] チェックボックスがオンになっている Android の設定画面のスクリーンショット。

ウェブ上でモーションを削除する

メディアクエリ レベル 5 では、ウェブに対するモーションが低減されたユーザー選択も提供されます。メディアクエリを使用すると、作成者はレンダリングされるドキュメントに関係なく、ユーザー エージェントまたは表示デバイスの値や機能をテストしてクエリできます。メディアクエリ prefers-reduced-motion は、ユーザーがオペレーティング システムの設定で、使用するアニメーションやモーションの量を最小限に抑えるように設定しているかどうかを検出するために使用されます。指定可能な値は次の 2 つです。

  • no-preference: 基盤となるオペレーティング システムをユーザーが設定していないことを示します。このキーワード値は、ブール値コンテキストで false と評価されます。
  • reduce: ユーザーがオペレーティング システムの設定で、インターフェースの移動またはアニメーションの最小化を(重要でないすべての動きが削除されるまで)最小にする必要があることを示します。

CSS および JavaScript コンテキストからメディアクエリを操作する

他のメディアクエリと同様に、prefers-reduced-motion は CSS コンテキストと JavaScript コンテキストから確認できます。

両方を説明するために、ユーザーにクリックしてもらいたい重要な登録ボタンがあるとします。人目を引く「バイブレーション」アニメーションを定義することもできますが、優れたウェブ市民として、アニメーションの使用を明示的に許可するユーザーに対してのみ再生します。それ以外のユーザー(アニメーションを無効にしているユーザーや、メディアクエリを理解しないブラウザのユーザーなど)に対しては再生しません。

/*
  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 Client Hints ヘッダーを使用すると、サイトはリクエスト時に必要に応じてユーザーのモーション設定を取得できます。これにより、サーバーはパフォーマンス上の理由から適切な CSS をインライン化できます。

デモ

Rogério Vicente 氏による 🐈? HTTP status cats についての簡単なデモを作成しました。まず ジョークをありがとう それは面白いので戻ってきたので、デモを紹介します。下にスクロールすると、各 HTTP ステータス 猫が右側または左側から交互に表示されます。滑らかな 60 FPS アニメーションですが、前述のとおり、一部のユーザーはこれを気に入らなかったり、さらに動きが気になるかもしれません。そのため、このデモは prefers-reduced-motion を尊重するようにプログラムされています。これは動的に機能するため、ユーザーは設定を即座に変更でき、再読み込みの必要はありません。ユーザーが動きの低減を希望する場合、不要な出現アニメーションは表示されなくなり、通常のスクロール モーションのみが残されます。以下のスクリーンキャストは、実際のデモを示しています。

prefers-reduced-motion デモアプリの動画

まとめ

最新のウェブサイトでは、ユーザーの好みを尊重することが重要であり、ウェブ デベロッパーがそれを実現できるよう、ブラウザはますます多くの機能を公開しています。また、prefers-color-scheme もリリースされています。これは、ユーザーがライトとダークのカラーパターンのどちらを好むかを検出します。prefers-color-scheme について詳しくは、Hello Darkness, My Old Friend 🌒? の記事をご覧ください。

CSS ワーキング グループは、現在、prefers-reduced-transparency(ユーザーが透明度を下げることを好むかどうかを検出する)、prefers-contrast(ユーザーがシステムに隣接する色のコントラストの増減量を要求したかどうかを検出する)、inverted-colors(ユーザーが反転色を好むかどうかを検出する)など、より多くのユーザー設定のメディアクエリの標準化を進めています。

(補足)すべてのウェブサイトでモーションの軽減を強制する

すべてのサイトで prefers-reduced-motion が使用されるとは限りません。また、ご自身の好みに合わない場合もあります。なんらかの理由で、すべてのウェブサイトでモーションを停止したい場合は、実際に設定できます。これを実現する 1 つの方法は、次の 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 を介して開始されたモーションを停止できないなど)。そのため、破損に気づいたら必ずこの機能を無効にしてください。

謝辞

Chrome に prefers-reduced-motion を実装してくれた Stephen McGruer は、Rob Dodson とともにこの記事もレビューしています。ヒーロー画像(Hannah Cauhepe 氏、Unsplash より)