prefers-reduced-motion メディアクエリは、ユーザーが使用するアニメーションやモーションの量を最小限に抑えるようオペレーティング システムにリクエストしたかどうかを検出します。
装飾的なアニメーションや遷移を好まないユーザーもいます。また、パララックス スクロールやズーム エフェクトなどが表示されると、酔ってしまうユーザーもいます。ユーザー設定メディア クエリ prefers-reduced-motion
を使用すると、この設定を指定しているユーザー向けに、動きを抑えたサイトのバリエーションを設計できます。
現実世界やウェブでの動きが激しすぎる
先日、子どもたちとアイススケートをしていました。晴天の下、アイスリンクは人でいっぱいでした ⛸。唯一の問題は、私は人混みに弱いことです。動くターゲットが非常に多いため、何にも集中できず、迷子になり、視覚的な過負荷を感じます。蟻塚を見つめているような感覚です。🐜?
![アイススケートを履いた人々の足が並んでいる。](https://web.developers.google.cn/static/articles/prefers-reduced-motion/image/throng-feet-ice-skating-57c271f1a5c82.jpg?authuser=6&hl=ja)
ウェブでも同様のことが起こることがあります。点滅する広告、派手なパララックス エフェクト、驚きのアニメーション、自動再生される動画など、ウェブはときに圧倒されるほど過剰な情報量になることがあります。幸い、現実世界とは異なり、その問題を解決する方法があります。CSS メディアクエリ prefers-reduced-motion
を使用すると、デベロッパーは、モーションの抑制を好むユーザー向けにページのバリエーションを作成できます。たとえば、動画の自動再生を控えたり、純粋に装飾的な効果を無効にしたり、特定のユーザー向けにページを完全に再設計したりできます。
この機能について詳しく説明する前に、ウェブでアニメーションがどのように使用されているかについて考えてみましょう。必要に応じて、背景情報をスキップして技術的な詳細に直接ジャンプすることもできます。
ウェブ上のアニメーション
アニメーションは、アクションが受信されて処理中であることをユーザーに知らせるなど、ユーザーにフィードバックを提供するためによく使用されます。たとえば、ショッピング ウェブサイトでは、商品をアニメーション化して仮想ショッピング カート(サイトの右上にあるアイコン)に「飛ばす」ことができます。
別のユースケースでは、スケルトン スクリーン、コンテキスト メタデータ、低品質の画像プレビューを組み合わせて、ユーザーの時間を多く消費し、全体的なエクスペリエンスが速く感じられるようにすることで、モーションを使用してユーザーの認識をハックします。ユーザーにこれから何が起こるかの状況を伝え、その間にできるだけ早くコンテンツを読み込むことを目的としています。
最後に、アニメーション グラデーション、パララックス スクロール、背景動画など、装飾的な効果があります。多くのユーザーはこのようなアニメーションを楽しんでいますが、アニメーションによって気が散ったり、動作が遅くなったりすると感じて、アニメーションを好まないユーザーもいます。最悪の場合、ユーザーはまるで現実世界にいるかのように、乗り物酔いを引き起こす可能性もあります。このようなユーザーにとって、アニメーションを減らすことは医学的な必要性です。
運動誘発性前庭スペクトラム障害
一部のユーザーは、アニメーション コンテンツによって注意が散漫になったり、吐き気を感じたりします。たとえば、スクロールに関連付けられたメイン要素以外の要素が大きく動くと、スクロール アニメーションによって前庭障害が発生する可能性があります。たとえば、パララックス スクロール アニメーションでは、背景要素が前景要素とは異なる速度で移動するため、前庭障害を引き起こす可能性があります。前庭(内耳)障害の反応には、めまい、吐き気、片頭痛などがあり、回復のために安静が必要になることがあります。
オペレーティング システムでモーションを削除する
多くのオペレーティング システムには、長い間、動きを抑える設定を指定するためのユーザー補助設定がありました。次のスクリーンショットは、macOS Mojave の [モーションを減らす] 設定と Android Pie の [アニメーションを削除] 設定を示しています。これらの設定をオンにすると、オペレーティング システムはアプリの起動アニメーションなどの装飾効果を使用しなくなります。アプリ自体もこの設定を尊重し、不要なアニメーションをすべて削除する必要があります。
![[動きを減らす] チェックボックスがオンになっている macOS の設定画面。](https://web.developers.google.cn/static/articles/prefers-reduced-motion/image/a-screenshot-the-macos-s-02f7529755e96.png?authuser=6&hl=ja)
![[アニメーションを無効化] チェックボックスがオンになっている Android の設定画面。](https://web.developers.google.cn/static/articles/prefers-reduced-motion/image/a-screenshot-the-android-94061601243dd.png?authuser=6&hl=ja)
ウェブ上でモーションを削除する
メディア クエリ レベル 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>
コンテキストのメディアクエリの操作
興味深いユースケースとしては、アニメーション化された 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-reduced-motion
デモアプリの動画
まとめ
ユーザーの設定を尊重することは、最新のウェブサイトにとって重要です。ブラウザは、ウェブ デベロッパーがこれを実現できるように、ますます多くの機能を公開しています。もう 1 つの例として、ユーザーが明るい配色と暗い配色のどちらを好むかを検出する 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 を使用して開始されたモーションを停止することはできません)。そのため、不具合に気付いた場合は必ず無効にしてください。
関連リンク
- メディアクエリ レベル 5 仕様の最新の編集者ドラフト。
- Chrome プラットフォームのステータスの
prefers-reduced-motion
。 prefers-reduced-motion
Chromium のバグ。- 投稿の実装に関する意向を点滅させます。
謝辞
Chrome に prefers-reduced-motion
を実装し、Rob Dodson とともにこのドキュメントを確認してくれた Stephen McGruer に感謝します。ヒーロー画像: Hannah Cauhepe、Unsplash より。