meguro.css 第8回 LTメモ

JavaScript, CSS

meguro.css で LT した時の話の雑まとめ。

TL;DR

  1. CSS アニメーションは変なのに依存しないから楽
  2. prefers-reduced-motion 色々とつらい
  3. CSS のプライバシー懸念事項

変なのに依存しない

requestAnimationFrame のようなフレームベースのアニメーションは、new Date()performance.now() という胡散臭い何かに依存するが、CSS Transition / Animation / WAAPI のアニメーションは、その辺 Pure でよさそう。
requestAniamtionFrameは callback に performance.now() を渡しているだけで、その callback 自体は Pure では?と思ってしまうけど、ブラウザ側で思わぬ副作用があるというお話。

requestAnimationFrame などの動作は、タイムスタンプを計測する特性上、リフレッシュレートや時間に強く依存する。
new Date()Performance.now() は、時間精度が Fingerprinting の対象となるため、ブラウザが Fingerprinting を抑制する場合に、予期しない動作を引き起こす。
例えばreact-spring の Issue がそう。

privacy.resistFingerprinting という設定が Firefox の「高度な設定」にある。
この設定は Tor Browser から移植されたもので、Tor Brower 同等の機能やバグを持つ。

この privacy.resistFingerprinting が時間の精度を下げ、performance.now() などで計測できる数値が 100ms 以上となる。これはアニメーションが理想としている 16.7ms 以下を超えているので、めっちゃカクカクした動きっぽくなる。 バグのように思えるが、仕様を考えるとこれが正しい挙動をしている。

jquery.Animate() や TweenMax などの主要アニメーションライブラリは、この設定の前には全滅する。
ただ、CSS や WAAPI では表現できないものがあったり、CSS Property 以外は操作できないものもある。
LT ではWeb Animations Level 2で挙がっている Custom Effects に触れたが、これはまだ Unofficial Draft である。

メディアクエリで変えられるのがいい話

アニメーションをやめたいケースについても調べた。

Windows, Mac, iOS などには、画面の視差効果を減らすための設定がある。
すべてのユーザーがアニメーションを望んでいるわけではないし、速度を遅くしてほしい場合がある。

Media Queries Level 5 で、prefers-reduced-motion: reduceというメディアクエリが存在する。

css

@media (prefers-reduced-motion: reduce) {
  .animationFoo {
    animation-duration: 0.01s !important;
  }
}

Animate.css など、この設定を利用しているライブラリもある。

CSS ではメディアクエリ一発でラクラクだが、JavaScript や主要フレームワーク/ライブラリではそれぞれ異なる対応が必要。

CSSのプライバシー懸念事項

アクセシビリティの観点で見られがちな prefers-reduced-motion というか Media Queries Level 5 だが、プライバシーの観点で見ると Fingerprinting の危険性をはらんでいる。
OS の設定を Web に反映させたいユーザーの要望を、コンテンツに対して公開しなければいけないため。
FingerPrinting のネタとしては十分で、JavaScript なら matchMedia で何かできる。

javascript

if (typeof window !== undefined &&
  window.matchMedia &&
  window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
    // 視差効果を減らす設定がオンの場合の処理
  }

privacy.resistFingerprinting ではその挙動も抑制していた。

反省

途中からブラウザ側の実装見るのが疲れて深掘りしていないこと