meguro.css 第8回 LTメモ
JavaScript, CSSmeguro.css で LT した時の話の雑まとめ。
TL;DR
- CSS アニメーションは変なのに依存しないから楽
- prefers-reduced-motion 色々とつらい
- 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
ではその挙動も抑制していた。
反省
途中からブラウザ側の実装見るのが疲れて深掘りしていないこと