FirefoxでSVGをアニメーションさせるSVGがガクつく!原因はブラウザのバグだった。

CSS

FirefoxでCSSアニメーションの挙動がおかしくなる現象に遭遇しました。
アニメーション自体は、複雑なものではなく、よくあるありきたりなアニメーションでした。
Firefoxは、シェアも低いわけではないので、今後のために記録を残しておきます。

  • Firefoxでのアニメーションがおかしくなる原因。
  • Firefoxでのアニメーションの解決方法。

以上について書いていこうと思います。

問題になっているアニメーションの詳細。

問題になっているアニメーションの詳細ですが、以下のとおりです。

  • Firefoxのみで発生。
  • SVGをtransformでY軸方向へ動かすと発生。
  • 左右に広がったり、ガクガクとした動きを見せる。

FirefoxでSVGをY軸方向へ動かそうとすると発生しています。
ただ、必ずしも発生するわけではなく、Firefoxでもバージョンによって、発生しない場合もありました。

問題になっている動作とコードの確認。

言葉で説明するだけでは、わかりずらいと思いますので、デモサイトで確認してみてください。

デモサイト

ガクガクというか、拡大縮小をしているようにみえますよね。

アニメーションの動作がおかしい原因を探ってみる。

Firefoxの一部のバージョンだけで発生しているので、スルーしてもいいのですが・・・見つけてしまった以上、気持ち悪いので解決していきたいと思います。

HTMLコード、CSSを変更しても効果がなかった。

まずは、コードを変えてみました。divではなく、picutureタグで囲ってみたり、pタグで囲ってみたりと、いろいろ試しましたが一向に解決しません。

HTMLコードが、原因ではないのかも知れません。

ということで、CSSを見てみますが・・・特殊な記述はしていないつもりなので、transfomで動かしているアニメーションをanimationに変えてみたりしてみましが、やはり効果ありませんでした。

原因はFirefoxのバグだった。

HTMLコードも違う、CSSの記述でもない。ということで、googleで検索をしてみたところ・・・Firefoxのバグのせいで発生しているかもしれないという記事を見つけました。

なにやら、以下の状況下のときにアニメーション(動き)に不具合があるとか。

  • SVGを動かす。
  • レンダリングされた画像にサブピクセルが発生している。

自分の状況を確認してみると・・・どちらも該当していました・・・。

ということで、Firefoxのバグが原因ということを前提に、なぜ発生するのか調べてみました。

サブピクセルを整数に戻そうとするFirefoxの機能が原因だった。

ブラウザのバグ報告をあさっていたところ、それっぽい原因をやっとみつけました。
私の現象に酷似していたので、おそらく間違いないかと思います。

バグ報告に載っていた事象を具体的に説明すると以下のような流れの中で発生するようです。

  1. 画像(SVG)が読み込まれる。
  2. サブピクセル(ピクセルに小数点以下)が発生する。
  3. Firefoxがピクセルを整数に戻そうとする機能が発動。再読み込み。
  4. 再読み込みされた画像にサブピクセルが発生する。
  5. 以降、「3.」に戻る。

といった具合で、3〜5が繰り返し、かつ高速で行われることで、ガタガタとした挙動を見せるようでした。縮小拡大を繰り返していたわけですね。

Firefoxには、サブピクセル(ピクセルの小数点以下)の値を整数に戻そうとする機能があるらしく、それが、アニメーションしている間ずっと動いてしまうようです。

そのため、アニメーションさせない画像については発生しているのかもしれませんが、アニメーションが付いていない分、目立たない(正確には認識できない。)だけのようです。

解決する方法。

原因はわかりました。次は解決方法です。
結論からいうと、原因がブラウザのバグのため、完全に解決することはできないようです。

ただ、解決とまではいかないものの、緩和して、認識できないまでには持っていくことができました。

その方法を、ご紹介しておきます。

  1. 要素にtransform: rotate(0.0001deg)を付与する。
  2. filter: blur(0px);を付与する。

上記の1もしくは、2をアニメーションさせる要素に付与してください。

上記の内容でなぜ解決するかというと、アニメーションさせている間、対象の要素をぼかしてあげることで、ガタガタという動作を認識させないようにする。といったものです。

解決ではなく、緩和といった意味はここにあります。
人間の目で認識できないようにすることで、限りなく自然な状態でアニメーションさせることができます。(正確には認識しずらくする。)

リセットCSSに記述しておく。

Firefoxは、シェアが高いわけではありませんが、カバーしておくブラウザに入ります。

また、SVGを使わずに構築することも少ないので、事前にリセットCSSなどのベースとなるスタイルシートに記述しておきましょう。

記述の仕方は、上記で説明した内容で問題ありません。

リセットCSSの書き方については、下記の記事で詳しく書いていますので、必要な方は読んでみてください。

関連記事

私が勤務する会社でコーディングのルールを決めることになりました。 ルールの中でリセットCSSはなにを使用するか。という議題になったので、私が調べた内容と、結論を記録しておこうと思います。 最後には、私が使っているノーマライズC[…]

まとめ

今回は、Firefoxのバグに悩まされた。という内容でした。

原因究明から解決まですごい時間がかかってしまいましたが、とても価値のある経験だったと思います。

本事象は11年も前から確認されている事象のようで、公式サイトでは解決済み。と、なっているにも関わらず、発生している事案です。

そう考えると、しばらく付き合っていかないといけない事案のような気がしますので、今回解決できたことは、大いに意味のあることだったと思います。

同じ事案で悩まされている方の参考になれば幸いです。