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

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

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

対応ブラウザ

  • 74
  • 79
  • 63
  • 10.1

ソース

現実世界やウェブで動きが多すぎる

先日、私は子供たちとアイススケートをしていました。晴れて太陽が輝き、スケートリンクにはたくさんの人で埋め尽くされた楽しい一日でした。動く標的があまりに多いので、何も注力できず、道に迷ってしまい、蟻マジックを見ているような感覚で完全に視覚的に過負荷になってしまいます。

アイススケートをする人の足の背筋が伸びています。
現実世界での視覚的な過負荷。

ときどき、ウェブでも同様のことが起こります。点滅する広告、派手な視差効果、驚くべき明らかなアニメーション、動画の自動再生など、ウェブでは圧倒されるほどのことが起こりえます...幸い、実生活とは異なり、それに対する解決策があります。CSS メディアクエリ prefers-reduced-motion を使用すると、動きの少ないユーザー向けのページのバリアントを作成できます。これには、動画の自動再生の禁止、特定の純粋な装飾効果の無効化、特定のユーザーに向けたページの全面的な再設計など、さまざまなものがあります。

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

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

アニメーションは、たとえば、アクションが受信されて処理中であることを知らせるフィードバックをユーザーに提供するためによく使用されます。たとえば、ショッピング ウェブサイトでは、仮想ショッピング カートに商品を移動するようにアニメーションで表示され、画面の右上隅にアイコンとして表示されます。

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

また、アニメーション グラデーション、視差スクロール、背景動画など、装飾的効果もあります。多くのユーザーはこのようなアニメーションを楽しんでいますが、気が散ったり動作が遅くなったりするため、気に入らないユーザーもいます。最悪の場合、ユーザーは現実の世界にいるかのように乗り物狂いに苦しむこともあるため、このようなユーザーにとっては、アニメーションを減らすことが医療上の必要性です。

運動による前庭スペクトル障害

ユーザーによっては、アニメーション コンテンツに対する不快感や吐き気を経験します。たとえば、スクロール アニメーションは、それに関連するメイン要素以外の要素が何度も動くと、前庭障害を引き起こす可能性があります。たとえば、視差スクロール アニメーションは、背景要素が前景要素とは異なる速度で動くため、前庭障害を引き起こす可能性があります。前庭(内耳)障害反応には、めまい、吐き気、片頭痛などがあり、時には寝床で休息する必要があります。

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

多くのオペレーティング システムは、長い間、動きの低減の設定を指定するユーザー補助設定を備えています。以下のスクリーンショットは、macOS Mojave の [Reduce motion] 設定と Android Pie の [Remove applications] 設定を示しています。オンにすると、オペレーティング システムはアプリの起動アニメーションなどの装飾効果を使用しません。アプリ自体もこの設定を尊重し、不要なアニメーションをすべて削除できます。

[動きの軽減] チェックボックスがオンになっている 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 クライアント ヒント ヘッダーを使用すると、サイトではリクエスト時にユーザーのモーション設定を必要に応じて取得でき、パフォーマンス上の理由から適切な CSS をインラインで挿入できます。

デモ

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

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

まとめ

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

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: 0s !important;
    transition-delay: 0s !important;
  }
}

この処理は、上記の CSS によってすべてのアニメーションと遷移の継続時間がオーバーライドされ、気づかなくなるほど短くなります。一部のウェブサイトは、正しく機能するためにアニメーションの実行に依存しているため(たとえば、あるステップが animationend イベントの呼び出しに依存している場合など)、より根本的な animation: none !important; アプローチでは機能しません。上記のハッキングであっても、すべてのウェブサイトで成功する保証はありません(たとえば、Web Animations API を介して開始された動きを停止できない)。そのため、破損に気づいたときは必ずハッキングを無効にしてください。

謝辞

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