Webサイトのロゴやアイコンがふっと描かれたり、スクロールに合わせて滑らかに変化したりする表現を見かけることが増えました。これらの多くはPNGやGIFではなく、SVG(Scalable Vector Graphics)というベクター画像とCSS・JavaScriptを組み合わせて作られています。本記事では、SVGアニメーションがなぜ軽量で扱いやすいのか、実際にどのような手順で実装するのかを初めての方にもわかる範囲で整理します。
SVGアニメーションが選ばれる理由
SVGは拡大しても輪郭がにじまないベクター形式のため、スマートフォンから大きなディスプレイまで同じファイルで綺麗に表示できます。さらにSVGは実体としてはテキストベースのXMLデータなので、パス(線の形)や塗り・線の太さをCSSやJavaScriptから直接操作できるのが最大の特徴です。連番画像を書き出す必要がなく、数KB程度のファイルサイズで滑らかな動きを作れるため、読み込み速度にも優しい手法といえます。
ロゴのアニメーション、アイコン切り替え、地図上のルート描画など、「小さく・繰り返し使われる・軽快に動いてほしい」パーツに特に向いています。
基本テクニック1: CSSでプロパティを動かす
最も手軽な方法は、SVG要素に通常のCSSアニメーションやトランジションを適用することです。fill(塗りの色)、stroke(線の色)、transform(回転・拡大・移動)は、HTML要素と同じようにCSSで変化させられます。
.icon-path {
transition: fill 0.3s ease, transform 0.3s ease;
}
.icon-path:hover {
fill: #2563eb;
transform: scale(1.08);
}
既存のCSSの知識がそのまま活かせる点が入りやすさにつながっています。ホバー時にアイコンが拡大したり色が変わったりする程度の表現なら、JavaScriptを書かずに完結できます。
基本テクニック2: 線を「描く」stroke-dasharray
SVGアニメーションらしい代表的な表現が、線がすっと描かれていくように見える「draw-on」効果です。これはstroke-dasharrayとstroke-dashoffsetという2つの属性を組み合わせて作ります。
考え方はシンプルです。stroke-dasharrayで線を「実線の長さ」と「隙間の長さ」に分割し、その値をパス全体の長さと同じにします。次にstroke-dashoffsetで実線部分を隙間側へずらして見えなくし、アニメーションでオフセットを0まで戻すことで、線が先端から伸びていくように見せかけます。
パス全体の長さはJavaScriptのelement.getTotalLength()で取得できます。
const path = document.querySelector('.line-path');
const length = path.getTotalLength();
path.style.strokeDasharray = length;
path.style.strokeDashoffset = length;
path.animate(
[{ strokeDashoffset: length }, { strokeDashoffset: 0 }],
{ duration: 1200, easing: 'ease-out', fill: 'forwards' }
);
GSAPなどのライブラリを使えば、イージング調整や複数パスの時間差(stagger)制御がより簡単になります。ロゴの輪郭や手書き風の署名、グラフの折れ線などに使うと効果的です。
基本テクニック3: スクロールと連動させる
draw-on効果は、ページの読み込み時だけでなく、スクロール量に応じて進行度を変える「スクラブ」という使い方をするとさらに表現の幅が広がります。ユーザーがスクロールした分だけ線が伸びていくため、地図のルートやタイムラインの進行、長い縦スクロールページの区切りに向いています。
実装の考え方は、stroke-dashoffsetの値を固定のアニメーション時間ではなく「現在のスクロール位置÷スクロール可能な全体量」といった0〜1の進捗値に紐づけることです。IntersectionObserverでパスが画面内に入ったタイミングを検知し、その後はscrollイベント(間引き処理あり)や、GSAPのScrollTriggerのようなscrub機能を使って進捗を計算すると実装が楽になります。
実装前の準備
コードを書く前のひと手間で、仕上がりが大きく変わります。
1. パスを整理する: デザインツールで作ったアイコンは不要なアンカーポイントが残っていることがあります。「パスの単純化」機能で点数を減らすと、getTotalLength()の長さも安定し描画スピードのムラが減ります。 2. viewBoxを確認する: viewBoxがずれていると拡大・縮小時に見た目が崩れます。書き出したSVGをテキストエディタで開きwidth・height・viewBoxの値を確認しましょう。 3. 不要な要素を消す: 自動付与されるグループやコメント、未使用のグラデーション定義は、ファイルサイズと保守性のために削除しておくのがおすすめです。
パフォーマンスとアクセシビリティへの配慮
SVGアニメーションは軽量とはいえ、同時に多数の要素を動かしたりfilterでぼかしを多用したりすると描画負荷が上がります。可能であればtransformとopacity、今回紹介したstroke-dashoffsetのような、ブラウザが得意とするプロパティに絞って動かすのが安全です。
また、装飾目的のアイコンにはaria-hidden="true"を付けて読み上げ対象から外し、意味を持つ図には適切なaria-labelを用意しましょう。prefers-reduced-motion: reduceが指定されている環境では、アニメーション時間を大幅に短縮するか最終状態を即時に表示するよう分岐しておくと、動きに敏感なユーザーにも配慮できます。
@media (prefers-reduced-motion: reduce) {
.line-path {
transition: none !important;
stroke-dashoffset: 0 !important;
}
}
まとめ
SVGアニメーションは、ベクターデータならではの軽さと、CSS・JavaScriptどちらからも操作できる柔軟さを兼ね備えた表現手法です。まずはfillやtransformをCSSで動かす小さな実験から始め、慣れたらstroke-dasharrayの描画効果、さらにスクロール連動へと段階的に広げていくと無理なくスキルを積み上げられます。小さなパーツに動きを添えるだけでも、サイト全体の印象は変わります。まずは手元の1つのアイコンから試してみてください。