2026年5月20日

2026年5月20日

WordPressでSVGアニメーションを使う方法(CSS・SMIL・Lottie)

SVG はベクター形式の画像なので、拡大しても粗くならず、CSS や SVG 自体の機能で動かせます。ローディング表示の回転、チェックマークを描く動き、アイコンの点滅などを、動画や GIF を使わずに作れます。

この記事では、WordPress のテーマやページで SVG アニメーションを使う方法を、置き場所の選び方から順に説明します。コードは、テーマ(子テーマ)を編集できることを前提にしています。

SVG をどこに置くかで、できることが変わる

置き方 CSS アニメーション SMIL ページ側の CSS・JavaScript から操作
HTML の中に <svg> を直接書く(インライン SVG) 使える 使える できる
<img src="icon.svg"> で読み込む SVG ファイルの中の <style> なら動く 動く できない
CSS の background-image で読み込む SVG ファイルの中の <style> なら動く 動く できない

<img> や背景画像として読み込んだ SVG は、ページとは別の文書として扱われます。SVG ファイルの中に書いたアニメーションは動きますが、ページ側の CSS で中の図形の色や動きを変えたり、JavaScript でスクロールに合わせて動かし始めたりすることはできません。この記事の例は、操作しやすいインライン SVG を中心にしています。

方法1: インライン SVG を CSS で回転させる

ローディング表示のように、SVG 全体を回転させる例です。テーマのテンプレートファイル(PHP)や、ブロックエディターの「カスタム HTML」ブロックに次の SVG を書きます。

<svg class="icon-spin" xmlns="http://www.w3.org/2000/svg"
     width="40" height="40" viewBox="0 0 24 24" aria-hidden="true">
  <circle cx="12" cy="12" r="10" fill="none"
          stroke="#2271b1" stroke-width="2" stroke-dasharray="48 15"/>
</svg>

CSS はテーマ(子テーマ)の style.css か、「追加 CSS」に書きます。

.icon-spin {
  animation: icon-spin 1s linear infinite;
}

@keyframes icon-spin {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}

/* 動きを減らす設定にしている人には止める */
@media (prefers-reduced-motion: reduce) {
  .icon-spin {
    animation: none;
  }
}

外側の <svg> 要素は HTML の要素と同じように扱われるため、中心を軸に回ります。SVG の中の図形(<circle> や <path>)を回す場合は、既定では SVG 全体の左上が回転の中心になります。図形の中心で回すには、その図形に次の指定を加えます。

.icon-spin circle {
  transform-box: fill-box;
  transform-origin: center;
}

「カスタム HTML」ブロックに書くときの注意

インライン SVG と <style> をブロックエディターに書けるのは、unfiltered_html の権限を持つユーザー(単一サイトでは管理者と編集者、マルチサイトではネットワーク管理者)だけです。投稿者や寄稿者が保存すると、許可されていないタグとして取り除かれます。何度も使う SVG は、テーマのテンプレートやテンプレートパーツに置くほうが管理しやすくなります。

方法2: 線を描くストロークアニメーション

円とチェックマークが描かれていくように見せる例です。線の長さと同じ値を stroke-dasharray と stroke-dashoffset に入れて線を隠し、stroke-dashoffset を 0 まで動かします。

<svg class="checkmark" xmlns="http://www.w3.org/2000/svg"
     width="60" height="60" viewBox="0 0 52 52" aria-hidden="true">
  <circle class="checkmark-circle" cx="26" cy="26" r="25"
          fill="none" stroke="#00a32a" stroke-width="2"/>
  <path class="checkmark-check" fill="none" stroke="#00a32a"
        stroke-width="3" d="M14.1 27.2l7.1 7.2 16.7-16.8"/>
</svg>
/* 円周 = 2 × 3.1416 × 25 ≒ 157.1 なので 158 を使う */
.checkmark-circle {
  stroke-dasharray: 158;
  stroke-dashoffset: 158;
  animation: checkmark-draw 0.6s ease-out forwards;
}

/* チェックの線の長さは約 33.8 なので 34 を使う */
.checkmark-check {
  stroke-dasharray: 34;
  stroke-dashoffset: 34;
  animation: checkmark-draw 0.3s ease-out 0.6s forwards;
}

@keyframes checkmark-draw {
  to { stroke-dashoffset: 0; }
}

/* 動きを止める場合は、線を描き終えた状態で表示する */
@media (prefers-reduced-motion: reduce) {
  .checkmark-circle,
  .checkmark-check {
    animation: none;
    stroke-dashoffset: 0;
  }
}

線の長さが正確にわからない図形では、ブラウザの開発者ツールのコンソールで document.querySelector('.checkmark-check').getTotalLength() を実行すると長さを確認できます。

動きを止めるときに animation: none だけを書くと、線が隠れたままになり何も表示されません。上のように stroke-dashoffset: 0 もあわせて指定します。

方法3: SMIL(SVG のアニメーション要素)を使う

SVG には、図形の中に <animate> などの要素を書いて動かす仕組み(SMIL)もあります。CSS を別に用意しなくてよく、<img> で読み込んだ SVG ファイルの中でも動きます。

<svg xmlns="http://www.w3.org/2000/svg" width="60" height="20"
     viewBox="0 0 60 20" role="img" aria-label="読み込み中">
  <circle cx="10" cy="10" r="6" fill="#2271b1">
    <animate attributeName="opacity" values="1;0.2;1" dur="1.2s" repeatCount="indefinite"/>
  </circle>
  <circle cx="30" cy="10" r="6" fill="#2271b1">
    <animate attributeName="opacity" values="1;0.2;1" dur="1.2s" begin="0.2s" repeatCount="indefinite"/>
  </circle>
  <circle cx="50" cy="10" r="6" fill="#2271b1">
    <animate attributeName="opacity" values="1;0.2;1" dur="1.2s" begin="0.4s" repeatCount="indefinite"/>
  </circle>
</svg>

SMIL の動きは CSS の prefers-reduced-motion では止まりません。動きを減らす設定に対応したい場合は、CSS アニメーションで作るか、インライン SVG なら JavaScript で SVG 要素の pauseAnimations() を呼んで止めます。

方法4: スクロールして見えたときに動かす

方法2 のチェックマークを、画面に入ったときに動かし始める例です。JavaScript が is-visible クラスを付けたときだけアニメーションを始めるように、CSS を書き換えます。

.animate-on-scroll .checkmark-circle,
.animate-on-scroll .checkmark-check {
  animation-play-state: paused;
}

.animate-on-scroll.is-visible .checkmark-circle,
.animate-on-scroll.is-visible .checkmark-check {
  animation-play-state: running;
}

SVG に class="checkmark animate-on-scroll" のようにクラスを足し、次の JavaScript を読み込みます(読み込み方は方法5 の wp_enqueue_script と同じです)。

// 要素が 30% 見えたら is-visible を付け、以後は監視をやめる
const targets = document.querySelectorAll('.animate-on-scroll');
const observer = new IntersectionObserver((entries) => {
  entries.forEach((entry) => {
    if (entry.isIntersecting) {
      entry.target.classList.add('is-visible');
      observer.unobserve(entry.target);
    }
  });
}, { threshold: 0.3 });

targets.forEach((el) => observer.observe(el));

この方法では、JavaScript が動かない環境ではアニメーションが止まったまま(線が隠れたまま)になります。表示されないと困る図形には使わないか、JavaScript で animate-on-scroll クラスを付けるように変えます。

方法5: Lottie のアニメーションを表示する

Lottie は、After Effects などで作ったアニメーションを JSON ファイルにし、ブラウザで SVG として再生する仕組みです。再生には lottie-web というライブラリを使います。

手順1: JSON ファイルをテーマに置く

WordPress のメディアライブラリは、初期設定では JSON ファイルのアップロードを受け付けません。アニメーションの JSON ファイルは、子テーマの中(例: animations/hero.json)に置きます。

手順2: lottie-web と初期化用のスクリプトを読み込む

子テーマの functions.php に次を追加します。例の lottie-web 5.13.0 は、2026年10月時点で cdnjs にある版です。

<?php
add_action( 'wp_enqueue_scripts', function () {
	wp_enqueue_script(
		'lottie-web',
		'https://cdnjs.cloudflare.com/ajax/libs/lottie-web/5.13.0/lottie.min.js',
		array(),
		'5.13.0',
		array( 'in_footer' => true )
	);
	wp_enqueue_script(
		'mytheme-lottie-init',
		get_theme_file_uri( 'js/lottie-init.js' ),
		array( 'lottie-web' ),
		'1.0.0',
		array( 'in_footer' => true )
	);
} );

get_theme_file_uri() は、子テーマにファイルがあれば子テーマの URL を、なければ親テーマの URL を返します。外部の CDN を使いたくない場合は、lottie-web のファイルをテーマに置いて読み込みます。

子テーマに js/lottie-init.js を作り、data-lottie 属性を持つ要素ごとにアニメーションを読み込みます。

// data-lottie 属性に書いた JSON ファイルを再生する
document.addEventListener('DOMContentLoaded', () => {
  const reduce = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
  document.querySelectorAll('[data-lottie]').forEach((el) => {
    lottie.loadAnimation({
      container: el,
      renderer: 'svg',
      loop: el.dataset.lottieLoop !== 'false',
      autoplay: !reduce, // 動きを減らす設定なら自動再生しない
      path: el.dataset.lottie,
    });
  });
});

手順3: テンプレートに表示する場所を作る

テンプレートファイルに、表示する場所を書きます。

<div class="hero-animation"
	data-lottie="<?php echo esc_url( get_theme_file_uri( 'animations/hero.json' ) ); ?>"
	data-lottie-loop="true"
	style="width: 300px; height: 300px;"
	aria-hidden="true"></div>

JSON ファイルを別のドメイン(CDN など)に置く場合は、そのサーバーがクロスオリジンの読み込みを許可している必要があります。同じサイトに置けば、この設定は要りません。

SVG ファイルをメディアライブラリにアップロードしたい場合

WordPress は初期設定では SVG ファイルのアップロードを許可していません。SVG は中に JavaScript を書ける形式のため、upload_mimes フィルターで拡張子を足すだけで許可すると、悪意のあるスクリプトを含む SVG がアップロードされるおそれがあります。

アップロードを許可する場合は、アップロード時に中身を無害化(サニタイズ)するプラグインを使います。たとえば 10up が開発する「Safe SVG」は、enshrined/svg-sanitize というライブラリでアップロードされた SVG をサニタイズし、アップロードできるユーザーを制限する設定も持っています。

なお、<img> で表示する SVG では、ファイル内に書いた JavaScript は実行されません。それでも、SVG ファイルの URL を直接開かれるとスクリプトが動く場合があるため、サニタイズは省かないようにします。

アクセシビリティの注意

  • 飾りの SVG には aria-hidden="true" を付け、スクリーンリーダーが読み上げないようにします。意味のある SVG には role="img" と aria-label を付けます。
  • OS やブラウザで「視差効果を減らす」「アニメーションを減らす」を選んでいる人には、prefers-reduced-motion: reduce で動きを止めるか小さくします。
  • 5 秒を超えて動き続ける表示には、止める手段を用意することが Web アクセシビリティの指針(WCAG 2.2 の達成基準 2.2.2)で求められています。読み込み中で操作できない間だけ出るローディング表示は、例外として扱われます。

まとめ

  • ページ側の CSS や JavaScript で動かすなら、SVG はインラインで書く。<img> で読み込む場合は SVG ファイルの中に動きを書く
  • 回転などは @keyframes と animation、線を描く動きは stroke-dasharray と stroke-dashoffset で作る
  • SMIL は <img> の中でも動くが、prefers-reduced-motion では止まらない
  • Lottie は lottie-web を wp_enqueue_script で読み込み、JSON はテーマの中に置く
  • SVG のアップロードは、サニタイズするプラグインを入れてから許可する

関連記事

お気軽にご相談ください

お見積りへ お問い合わせへ
▲