1735365841256
previous arrow
next arrow

SVGタグ解説

CSSとJavaScriptによる基本図形操作

1. はじめに (Introduction)

SVGとは何か:XMLベースのベクターグラフィック言語

SVG(Scalable Vector Graphics)は、W3C(World Wide Web Consortium)によって開発・維持されている、XMLに基づいたマークアップ言語です。主に二次元ベクターグラフィックを記述するために使用されます。HTMLがテキストコンテンツの構造化に用いられるのに対し、SVGはグラフィック、つまり図形、線、テキストなどの視覚的要素を構造化するための言語と位置づけられます。

SVGの最大の特徴の一つは、ベクター形式であることです。これは、画像をピクセルの集まりとして表現するビットマップ形式(JPEG、PNG、GIFなど)とは異なり、点、線、曲線といった数学的な記述に基づいてグラフィックを描画します。そのため、画像をどれだけ拡大・縮小しても、画質が劣化したり、いわゆる「ジャギー」(ギザギザした線)が現れたりすることがありません。これは、レスポンシブデザインや高解像度ディスプレイ(Retinaディスプレイなど)が普及した現代のウェブ開発において、非常に重要な利点となります。

W3Cという標準化団体によって策定されているため、SVGは特定のベンダーに依存しないオープンな標準技術であり、主要なモダンブラウザで広くサポートされています。

SVGの主な利点:スケーラビリティ、テキストベース、DOM操作可能性

SVGはウェブ開発において多くの利点を提供します。

  • スケーラビリティ: 前述の通り、ベクター形式であるため、どのようなサイズに変更しても鮮明な表示品質を維持します。これにより、一度作成したグラフィックを様々なデバイスや解像度で再利用することが容易になります。
  • テキストベース: SVGファイルの実体はXML形式のテキストファイルです。これは、テキストエディタで直接編集できるだけでなく、検索エンジンによるインデックス化が可能であり、Gzipなどで効率的に圧縮できるという利点ももたらします。また、ファイルサイズが比較的軽量になる傾向があります。
  • DOM操作可能性: SVG要素は、HTML要素と同様に、ブラウザによってDOM(Document Object Model)ツリーの一部として解釈されます。これは、JavaScriptを用いてSVG要素にアクセスし、その属性やスタイルを動的に変更したり、イベントを追加したりできることを意味します。この特性が、インタラクティブなデータビジュアライゼーションや動的なグラフィック表現を実現するための鍵となります。
  • CSSによるスタイリング: SVG要素の見た目(色、線の太さ、不透明度など)は、CSSを使用して柔軟に制御できます。これにより、ウェブサイト全体のデザインシステムとの一貫性を保ちやすくなり、:hoverなどの擬似クラスを用いたインタラクションも容易に実装できます。
  • アクセシビリティ: SVG内のテキスト要素はテキストとして認識されるため、スクリーンリーダーなどで読み上げ可能です。また、<title>要素や<desc>要素、WAI-ARIA属性を用いることで、グラフィックの内容に関する代替情報を提供し、アクセシビリティを向上させることができます。

SVGはその利用方法によって、その性質が大きく変わるという二面性を持っています。一つは、JPEGやPNGのように、<img>タグのsrc属性やCSSのbackground-imageプロパティで参照される「画像ファイル」としての側面です。この場合、SVGは基本的に静的な画像として扱われ、外部のCSSやJavaScriptから内部の要素を直接操作することはできません。

もう一つは、HTMLドキュメント内に<svg>タグとその内容を直接記述する「インラインSVG」としての側面です。この場合、SVG要素はHTMLのDOMの一部となり、前述のDOM操作可能性やCSSによるスタイリングといった利点を最大限に活用できます。

2. SVGの基本構造 (Basic SVG Structure)

<svg>要素:ルート要素、基本的な属性 (width, height, viewBox) の解説

SVGコンテンツを作成する際の基本となるのが<svg>要素です。これはSVGドキュメントのルート(根)要素、あるいはコンテナとして機能し、内部に記述される様々な図形要素(<rect>, <circle>など)やグループ要素(<g>)を包含します。

<svg>要素には、その表示領域や内部コンテンツのマッピング方法を定義するための重要な属性がいくつかあります。

  • width属性とheight属性: これらは、SVGが表示される物理的な領域の幅と高さ、つまりビューポート(表示領域)のサイズを指定します。値はピクセル (px)、em、パーセンテージ (%) などのCSSで有効な長さの単位で指定できます。単位を省略した場合は、通常ピクセルとして解釈されます。
  • viewBox属性: この属性は、SVGコンテンツのどの部分を、どのようにビューポートに表示するかを定義します。値はスペースまたはカンマで区切られた4つの数値 min-x min-y width height で構成されます。
  • xmlns属性: SVGはXMLベースの言語であるため、SVG要素がSVGの名前空間 (http://www.w3.org/2000/svg) に属することを示すためにxmlns属性を指定することが推奨されます。

SVG座標系とviewBoxの関係性

SVGグラフィックは、独自の座標系(ユーザー座標系)内で定義されます。通常、この座標系の原点(0,0)はビューポートの左上隅に位置し、X軸は右方向、Y軸は下方向が正の値となります。

viewBox属性は、このユーザー座標系のどの領域を<svg>要素のwidth属性とheight属性で定義された物理的なビューポートにマッピングするかを指定します。例えば、<svg width="200" height="100" viewBox="0 0 50 50"> と指定した場合、ユーザー座標系の(0,0)から(50,50)までの範囲が、幅200px、高さ100pxのビューポート全体に表示されるように拡大・縮小されます。

viewBox属性とpreserveAspectRatio属性を理解し、適切に使用することは、SVGを意図した通りに表示させ、特にレスポンシブデザインに対応させる上で非常に重要です。

3. SVG基本図形タグ (Basic SVG Shape Tags)

SVGには、基本的な幾何学的形状を描画するための専用タグが用意されています。これらを使うことで、複雑なパスデータを記述することなく、一般的な図形を簡単に作成できます。

<rect> (長方形)

<rect>要素は、長方形を描画するために使用されます。

<svg width="220" height="100" viewBox="0 0 220 100">
  <rect x="10" y="10" width="100" height="80" fill="lightblue" stroke="black" />
  <rect x="120" y="10" width="90" height="80" rx="15" ry="10" fill="lightgreen" stroke="darkgreen" stroke-width="2"/>
</svg>

<circle> (円)

<circle>要素は、円を描画します。

<svg width="100" height="100" viewBox="0 0 100 100">
  <circle cx="50" cy="50" r="40" fill="orange" stroke="brown" stroke-width="3"/>
</svg>

<ellipse> (楕円)

<ellipse>要素は、楕円を描画します。

<svg width="200" height="100" viewBox="0 0 200 100">
  <ellipse cx="100" cy="50" rx="80" ry="30" fill="pink" stroke="red" />
</svg>

<line> (線)

<line>要素は、2つの点の間に直線を引くために使用されます。最も単純な図形の一つです。

  • 主要属性:
    • x1: 始点のX座標
    • y1: 始点のY座標
    • x2: 終点のX座標
    • y2: 終点のY座標
    • stroke: 線の色
    • stroke-width: 線の太さ
<svg width="100" height="100" viewBox="0 0 100 100">
  <line x1="10" y1="10" x2="90" y2="90" stroke="black" stroke-width="5" />
</svg>

<text> (テキスト)

<text>要素は、SVGグラフィック内にテキストを描画するために使用されます。

<svg width="300" height="100" viewBox="0 0 300 100">
  <style>
.my-text {
      font-family: sans-serif;
      font-size: 20px;
    }
  </style>
  <text x="10" y="30" class="my-text" fill="blue">左揃え (start)</text>
  <text x="150" y="60" class="my-text" fill="green" text-anchor="middle">中央揃え (middle)</text>
  <text x="290" y="90" class="my-text" fill="red" text-anchor="end">右揃え (end)</text>
</svg>

4. SVGのスタイリング (Styling SVG)

SVG要素の見た目(色、線、透明度など)を制御するには、主に2つの方法があります:プレゼンテーション属性とCSSです。

プレゼンテーション属性 (fill, stroke, stroke-width) による方法

SVG要素のタグ内に直接、スタイルを指定する属性を記述する方法です。

  • fill: 図形の内部を塗りつぶす色を指定します。
  • stroke: 図形の輪郭線の色を指定します。
  • stroke-width: 輪郭線の太さを指定します。

CSSによる方法 (<style>タグ、外部CSS、インラインスタイル)

プレゼンテーション属性の代わりに、CSS(Cascading Style Sheets)を使用してSVG要素のスタイルを指定することも可能です。

<svg width="200" height="100" viewBox="0 0 200 100">
  <defs>
    <style>
.my-circle {
        fill: orange;
        stroke: brown;
        stroke-width: 2;
      }
.my-circle:hover {
        fill: yellow;
      }
    </style>
  </defs>
  <circle class="my-circle" cx="50" cy="50" r="40" />
</svg>

グループ化とスタイルの継承 (<g>タグ)

<g>(group)タグは、複数のSVG要素を一つのグループとしてまとめるためのコンテナ要素です。<g>タグに適用されたスタイルは、グループ内の子要素に継承されます。

5. JavaScriptによるSVG操作 (Manipulating SVG with JavaScript)

SVGの大きな利点の一つは、JavaScriptを使って動的に操作できることです。特にインラインSVGの場合、SVG要素はDOMの一部として扱われるため、標準的なDOM操作APIを用いてインタラクティブな表現を実現できます。

SVG要素へのアクセス (DOM操作: getElementById, querySelector)

インラインSVG内の特定の要素をJavaScriptで操作するには、まずその要素への参照を取得する必要があります。これは、HTML要素を取得するのと同様の方法で行えます。

// IDで取得
const circleElement = document.getElementById('myCircle');

// CSSセレクタで取得
const rectElement = document.querySelector('#myRect');

属性の動的な変更 (setAttribute)

JavaScriptでSVG要素への参照を取得できれば、その要素の属性値を動的に変更できます。これにより、図形の位置、サイズ、色などをプログラムで制御することが可能になります。

const circle = document.getElementById('myCircle');

// cx属性の値を100に変更
circle.setAttribute('cx', '100');

// 半径rを50に変更
circle.setAttribute('r', '50');

// fill属性を緑に変更
circle.setAttribute('fill', 'green');

スタイルの動的な変更 (element.style)

SVG要素のスタイルもJavaScriptで動的に変更できます。element.styleプロパティを通じて個々のCSSプロパティを変更する方法が一般的です。

const rect = document.getElementById('myRect');

// 塗り色を赤に
rect.style.fill = 'red';

// 線の色を黄色に
rect.style.stroke = 'yellow';

// 線の太さを5pxに
rect.style.strokeWidth = '5px';

イベントリスナーの追加 (addEventListenerによるインタラクション)

SVG要素にユーザーの操作(クリック、マウスオーバーなど)に対する応答を追加するには、addEventListener()メソッドを使用します。

const interactiveCircle = document.getElementById('myCircle');

// クリックイベント
interactiveCircle.addEventListener('click', (event) => {
  console.log('Circle clicked!');
  // 例: クリックされたら色を変える
  event.target.setAttribute('fill', 'magenta');
});

6. 実践的なコード例 (Practical Code Examples)

静的な図形の描画例

以下のコードは、JavaScriptを使用せず、SVGの各図形タグと属性のみで静的な図形を描画する例です。

<svg width="400" height="250" viewBox="0 0 400 250" style="border: 1px solid #ccc;">
  <!-- 30度回転した長方形 -->
  <rect x="20" y="40" width="100" height="60" fill="red" stroke="black" stroke-width="2" transform="rotate(30 70 50)" />

  <!-- 太い緑枠の黄色い円 -->
  <circle cx="220" cy="60" r="40" fill="yellow" stroke="green" stroke-width="8" />

  <!-- 120度回転した青い点線の楕円 -->
  <ellipse cx="80" cy="170" rx="60" ry="30" fill="none" stroke="blue" stroke-width="3" stroke-dasharray="10 5" transform="rotate(120 80 170)" />

  <!-- テキスト -->
  <text x="300" y="175" font-family="serif" font-size="24" fill="purple" text-anchor="middle" dominant-baseline="middle">のんきの日記</text>

  <!-- 平行な線 -->
  <line x1="220" y1="130" x2="380" y2="130" stroke="darkgreen" stroke-width="2" />
  <line x1="220" y1="140" x2="380" y2="140" stroke="blue" stroke-width="2" />
</svg>

表示例:

のんきの日記

JavaScript/CSSによるSVG操作メソッド・プロパティ早見表

操作対象 (属性/スタイル) 要素例での属性名 JavaScriptでの操作方法 (例) CSSでの操作方法 (プロパティ) 簡単な説明
位置 (X座標) cx, x el.setAttribute('cx', val) cx: val; ¹ 図形の水平位置
位置 (Y座標) cy, y el.setAttribute('cy', val) cy: val; ¹ 図形の垂直位置
サイズ (半径) r (円) el.setAttribute('r', val) r: val; ¹ 円の半径
サイズ (幅) width (長方形) el.setAttribute('width', val) width: val; ¹ 長方形の幅
塗り色 fill el.style.fill = color fill: color; 図形の塗りつぶし色
線色 stroke el.style.stroke = color stroke: color; 図形の線の色
線幅 stroke-width el.style.strokeWidth = val stroke-width: val; 図形の線の太さ
テキスト内容 (テキストノード) el.textContent = text (CSSでは不可) テキスト要素の内容
イベント処理 (クリックなど) el.addEventListener('click', func) :hover, :active など ユーザーインタラクション

¹ これらのジオメトリ関連プロパティをCSSで直接指定する機能はSVG 2仕様で導入されましたが、ブラウザサポートはまだ限定的です。JavaScriptのsetAttributeを使用するのが最も確実です。

7. 複雑な図形の描画 (<path>タグ)

<path>要素は、SVGで最も強力かつ汎用的な図形描画要素です。直線、曲線、円弧などを自由に組み合わせることで、<rect><circle>のような基本図形では表現できない、あらゆる複雑な形状を作成できます。

d属性:パスデータの定義

<path>要素の形状は、d属性に設定される一連のコマンド文字列によって定義されます。この文字列は「ペンを動かすための命令」の集まりと考えることができます。

各コマンドは、1文字の命令コード(例: Mは”Move to”)と、それに続く数値パラメータ(座標など)で構成されます。命令コードには大文字と小文字の区別があり、それぞれ異なる意味を持ちます。

  • 大文字コマンド (例: M, L, C): 絶対座標を指定します。SVGキャンバスの原点(0,0)を基準とした座標です。
  • 小文字コマンド (例: m, l, c): 相対座標を指定します。直前の描画点の位置を基準とした相対的な移動量です。

主要なパスコマンド

以下は、d属性でよく使用される主要なコマンドです。

コマンド 名称 パラメータ 説明
M x y
m dx dy
Moveto (移動) (x, y) ペンを指定した座標に移動させます。パスの描画を開始する点、または新しいサブパスを開始する点として使用します。
L x y
l dx dy
Lineto (直線) (x, y) 現在の点から指定した座標まで直線を引きます。
H x
h dx
Horizontal Lineto (水平線) x 現在の点から水平方向に直線を引きます。
V y
v dy
Vertical Lineto (垂直線) y 現在の点から垂直方向に直線を引きます。
C x1 y1, x2 y2, x y
c dx1 dy1, dx2 dy2, dx dy
Curveto (3次ベジェ曲線) (x1, y1), (x2, y2), (x, y) 2つの制御点 (x1,y1), (x2,y2) を使って、現在の点から終点(x,y)まで3次ベジェ曲線を引きます。
Q x1 y1, x y
q dx1 dy1, dx dy
Quadratic Curveto (2次ベジェ曲線) (x1, y1), (x, y) 1つの制御点 (x1,y1) を使って、現在の点から終点(x,y)まで2次ベジェ曲線を引きます。
A rx ry rot large-arc sweep x y
a rx ry rot large-arc sweep dx dy
Elliptical Arc (円弧) (rx, ry, rot, large-arc, sweep, x, y) 現在の点から終点(x,y)まで、楕円の円弧を引きます。パラメータが多く複雑ですが、円や楕円の一部を表現するのに使われます。
Z
z
ClosePath (閉じる) なし 現在の点から、現在のサブパスの開始点(最後のM/mコマンドの位置)まで直線を引いてパスを閉じます。

<path>のサンプル

<path>要素を使って、星や三角形といった基本図形タグでは直接描けない図形を作成する例です。

<svg width="400" height="200" viewBox="0 0 400 200" style="border: 1px solid #ccc;">
  <!-- 星の描画 -->
  <path d="M 50 10 L 65 45 L 100 45 L 75 70 L 85 105 L 50 85 L 15 105 L 25 70 L 0 45 L 35 45 Z" fill="gold" stroke="orange" stroke-width="2" transform="translate(30, 30) scale(0.8)" />
  <path d="M 50 10 L 65 45 L 100 45 L 75 70 L 85 105 L 50 85 L 15 105 L 25 70 L 0 45 L 35 45 Z" fill="#ffc0cb" stroke="deeppink" stroke-width="2" transform="translate(150, 60) scale(0.5)" />

  <!-- 三角形の描画 -->
  <path d="M 50 0 L 100 100 L 0 100 Z" fill="lightgreen" stroke="darkgreen" stroke-width="2" transform="translate(250, 20)" />
  <path d="M 50 0 L 100 50 L 0 50 Z" fill="skyblue" stroke="darkblue" stroke-width="2" transform="translate(280, 130)" />
</svg>

表示例:

8. まとめと次のステップ (Conclusion and Next Steps)

主要な学習ポイントの要約

本レポートでは、SVGの基本的な概念から、CSSとJavaScriptを用いた具体的な操作方法までを解説しました。SVGはスケーラブルで、DOM操作が可能であり、インタラクティブなウェブコンテンツを作成するための強力なツールです。

さらなる学習のためのリソース紹介

SVGは非常に奥が深く、多機能な技術です。さらに深く学習を進めたい場合は、以下のリソースが役立つでしょう。

次のステップ

SVGの基本を理解したら、以下のようなトピックに挑戦してみることをお勧めします。

  • SVGアニメーション: SMIL, CSS, JavaScriptを用いたアニメーション。
  • SVGフィルター効果: ぼかしや影などの視覚効果。
  • データビジュアライゼーション: D3.jsなどのライブラリとの連携。