HTML GIF 再生

HTML GIF 再生の方法

要約

この記事では、HTMLでGIFアニメーションを再生するための技術と手法について説明します。GIFの特性やブラウザでの表示方法、最適化のポイントに焦点を当てています。

GIFアニメーションの基本

GIFアニメーションは、画像の連続表示により動きを表現する形式です。この形式は、ウェブ上での表現において非常に人気があります。HTMLでのGIFの使用方法や、アニメーションのループ設定について解説します。

HTMLでのGIFの表示方法

GIFアニメーションをHTMLに埋め込む方法は非常にシンプルです。以下のコード例のように、<img>タグを使用してGIFファイルを表示できます。

以下はサンプルコードです:


<img src="sample.gif" alt="Sample GIF">

GIFの最適化

ウェブページの読み込み速度を向上させるために、GIFファイルを最適化することが重要です。以下の表は、GIFの最適化に関する一般的な手法を示しています。

最適化手法 説明
フレーム削減 使用しないフレームを削除してファイルサイズを小さくする。
色数の制限 使用する色の数を減らしてファイルサイズを最適化する。
圧縮ツール使用 専門のソフトウェアを用いてGIFを圧縮する。

自動再生するGIF要素をユーザーが停止できるように実装する

そんな中、直近で携わったWebサイトの実装案件で、固定ヘッダーに動き続けるGIFのロゴを実装する場面に出くわしました。(実際はGIFファイルではないですが、詳細を伝えると身バレする可能性があるためGIFとして進めます)

どう実装しようか調べていたところ、X(旧Twitter)でprefers-reduced-motionを使って実装した例の話を聞いて、その手があったか!と思い早速実装しました。

prefers-reduced-motionは、ユーザーがOSの設定でモーションを減らす設定をしているかどうかを判定できるCSSメディアクエリです。
例えば、iPhoneの場合、「視差効果を減らす」という設定をONにするとprefers-reduced-motionの値がreduceになり、アニメーションが減ったりユーザーインターフェイスの動きが減ったりします。(筆者も普段はONにしています)

もちろんiPhone以外のAndroidやWindows,Macなどでも同様の設定があります。(名称は異なります)

HTML pictureタグを使った方法

prefers-reduced-motionを使って、モーションを減らす設定をしているユーザーにはアニメーションGIFではなく静止画を表示する方法を紹介します。
HTMLのpictureタグとsourceタグを使うことで、簡単に実装できます。

index.html

<picture>
  <source srcset="./assets/img/logo.svg" media="(prefers-reduced-motion: reduce)" />
  <img src="./assets/img/logo.gif" alt="" width="100" height="50" />
</picture>
  • sourceタグでmedia="(prefers-reduced-motion: reduce)"を指定することで、prefers-reduced-motionの値がreduce(視差効果を減らすをON)の場合にのみ、そのsourceタグ内の画像が表示されます。

  • 上記の例では、reduceの場合は動きのないSVGファイル(./assets/img/logo.svg)が表示され、そうでない場合はGIFファイル(./assets/img/logo.gif)が表示されます。

この判定に関してはmedia="(prefers-reduced-motion: no-preference)"として処理を逆にして表示しても問題ないかと思います。

CSS, JavaScriptでもできる

prefers-reduced-motionを使ったアニメーションの制御は、CSSやJavaScriptでも行うことができます。

3-1. CSSで制御する場合

CSSの@mediaルールを使って、prefers-reduced-motionの値に応じてスタイルを適用することができます。

style.css

@media (prefers-reduced-motion: reduce) {
  /* アニメーションを無効にしたときのプロパティと値 */
  .logo {
    animation: none;
  }
}

上記の例では、prefers-reduced-motionの値がreduceの場合に、.logoというクラスがついた要素のアニメーションを無効にしています。

3-2. JavaScriptで制御する場合

JavaScriptのwindow.matchMediaメソッドを使うことで、prefers-reduced-motionの値を取得し、それに応じて処理を実行することができます。

main.js

const mediaQuery = window.matchMedia("(prefers-reduced-motion: reduce)");

if (mediaQuery.matches) {
  // アニメーションを無効にしたときの処理
  const logo = document.querySelector('.logo');
  logo.style.animation = 'none';
}

上記の例では、prefers-reduced-motionの値がreduceの場合に、.logoというクラスがついた要素のアニメーションを無効にしています。

iOS17から追加された「アニメーション画像自動再生」

iOS17から、アクセシビリティ設定に「アニメーション画像自動再生」という項目が追加されました。
この設定をOFFにすると、GIF画像などのアニメーション画像が自動的に再生されなくなります。

上記のprefers-reduced-motionを使ったコードでPCでもスマホでも動作することを確認できましたが、iPhoneのアクセシビリティの動作の設定で、iOS17から追加された「アニメーション画像自動再生」という設定に気づきました。

どういう仕様なのかいまいち分からなかったので、上記のコードを用いてiPhoneで実機検証してみました。

検証方法:iPhoneで設定を組み合わせてWebサイトのGIF要素を見る

以下、GIFファイルがどういう挙動を取るかの結果です。

視差効果を減らす アニメーション画像自動再生 GIF 結果
ON ON 動かない
ON OFF 動かない
OFF ON 動く
OFF OFF 動かない

ほとんど動かない結果となりました。
わかったことは、WebサイトのGIFファイルに関しては「視差効果を減らす」の設定より、「アニメーション画像自動再生」の設定の方が優先度が高い、ということですね。

この「アニメーション画像自動再生」について少し調べてみましたが、今のところON/OFFをデバッグする方法はなさそうでした。。。(内部的にどのような処理をしているのかも不明)

ちなみにAppleサイトでは以下のように説明されていました。

アニメーション画像の自動再生: オフにする。(オンの場合、「メッセージ」やSafariでのGIFなど、動きの速いアニメーション画像や移動する要素が自動再生されます。)

リセットCSSに気をつけよう

近年、モダンなリセットCSSとして人気のある「modern CSS reset」などを利用している場合、prefers-reduced-motionを使ったアニメーション制御がすでに組み込まれていることがあります。

以下は、いくつかのリセットCSSの例です。

modern CSS reset (Andy Bell)

/* Remove all animations and transitions for people that prefer not to see them */
@media (prefers-reduced-motion: reduce) {
  html:focus-within {
   scroll-behavior: auto;
  }
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

acab/reset.css (Nicolas Gallagher)

@media (prefers-reduced-motion: no-preference) {
	:where(html:focus-within) {
		scroll-behavior: smooth;
	}
}

EllyLoel/reset.css (Elly Loel)

/* Animate focus outline */
@media (prefers-reduced-motion: no-preference) {
  :focus-visible {
    transition: outline-offset 145ms cubic-bezier(0.25, 0, 0.4, 1);
  }
  :where(:not(:active)):focus-visible {
    transition-duration: 0.25s;
  }
}

これらのリセットCSSを利用している場合、animationtransitionのプロパティを使用すると、iPhoneの「視差効果を減らす」などをONにしたときに、ほぼ再生しないように見える可能性があります。

以前、このリセットCSSに気づかずに自分のスマホだけアニメーションの挙動が異なっていて、原因を特定するのに苦労した経験があります。

アニメーションを多用するサイトでは、実機検証の際にprefers-reduced-motionを有効化した場合としていない場合の両方で、アニメーションがどのように見えるかを確認することをおすすめします。

おまけ:GIFよりMP4を使おう

アニメーション画像を実装する場合、近年ではGIFよりもMP4の方が推奨されています。
MP4は、GIFよりもファイルサイズが小さく、画質も優れているため、Webサイトのパフォーマンス向上に繋がります。

Appleのdeveloperサイトでも、以下のように明記されています。

GIFs can be up to 12 times as expensive in bandwidth and twice as expensive in energy use when compared to a modern video codec. Instead, use H.264-encoded MP4 files for animations;

(Google翻訳:最新のビデオコーデックと比較すると、GIFは帯域幅で最大12倍、エネルギー使用量で2倍高価になる可能性があります。代わりに、アニメーションにはH.264でエンコードされたMP4ファイルを使用してください。)

デザイナーにアニメーション画像の作成を依頼する際は、MP4形式で作成してもらうように相談してみましょう。

まとめ

この記事では、Webサイトで自動再生するGIF要素を、ユーザーがシステム設定でモーションを減らす設定にしている場合に停止する方法を解説しました。

prefers-reduced-motionメディアクエリを使用することで、ユーザーのアクセシビリティ設定を尊重したWebサイトを作ることができます。

また、近年ではGIFよりもMP4の方がパフォーマンスが良い点も考慮し、適切なファイル形式を選択するようにしましょう。

参考文献

GIFアニメーションに関する詳細な情報については、以下のリンクをご覧ください:

よくある質問 (QA)

Q1: GIFと動画の違いは何ですか?

A1: GIFは無音のアニメーション形式で、主に短いループアニメーションに使用されます。一方、動画は音声と高解像度の映像をサポートしています。

Q2: GIFファイルはどれくらいのサイズが理想的ですか?

A2: 理想的なGIFファイルのサイズは、用途により異なりますが、一般的には500KB以下が推奨されます。これにより、ページの読み込み速度が向上します。

Q3: GIFのループを設定する方法は?

A3: GIFのループ設定は、GIFを作成する際に選択できます。多くのGIF作成ツールには、ループ回数を指定するオプションがあります。

その他の参考記事:html gif 埋め込み