SVGファイルをテキストエディタで開くと、<svg>やviewBox、pathなどの英語と数字がずらりと並んでいて、どこを見ればよいのか分からなくなりませんか。
SVGのコードは、実は「どの位置に、どんな図形を、どの大きさで描くか」を書き並べたものなので、基本のルールを知ればシンプルな図形は読めるようになります。
SVG入門シリーズの7回目です。
この記事では、SVGのコードの基本構造(svg要素・xmlns・width/height・viewBox)と、rect・circle・line・text・pathといった基本図形の書き方を、コードと実際の表示結果を並べて初心者向けに解説します(SVGそのものについてはSVGファイルとはで解説しています)。
SVGのコードの基本
まずは、SVGのコードがどんな部品でできているかと、図形の位置を決める座標・viewBoxの考え方を押さえましょう。
SVGのコードは「タグ」と「属性」でできている
SVGのコードは、「何を描くか」を表すタグと、「どこに・どの大きさで描くか」を表す属性の組み合わせでできています。
タグとは<rect>のように<と>で囲んだ命令のことで、属性とはwidth="180"のようにタグの中に書く「名前="値"」の設定のことです。
書き方のルールはHTMLとよく似ています(HTMLの基本はHTMLとはで解説しています)。
次のコードは、黄色い四角形の上に濃い黄色の円を1つ描いた、いちばんシンプルなSVGの例です。
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="120" viewBox="0 0 200 120">
<rect x="10" y="10" width="180" height="100" fill="#FFDF85"/>
<circle cx="100" cy="60" r="30" fill="#FFBD07"/>
</svg>
このコードの各部分の意味は、次の表のとおりです。
| コードの部分 | 呼び方 | 意味 |
|---|---|---|
<svg ...> | 開始タグ | ここからSVGの絵が始まる |
</svg> | 終了タグ | ここでSVGの絵が終わる |
<rect ... /> | 図形のタグ | 四角形を1つ描く。中身がないので、最後を/>で閉じる |
width="180" | 属性 | 「幅は180」という設定。名前="値"の形で書く |
<svg>から</svg>までを1枚の画用紙、その中のタグを画用紙に描く図形の1つ1つ、と考えると分かりやすくなります。
このように、タグで表される1つ1つの部品は「要素」とも呼ばれ、<rect>なら「rect要素」と言います。
svg要素とxmlns・width・height
一番外側の<svg>(svg要素)には、絵全体に関わる設定を属性として書きます。
| 属性 | 意味 | 上のコードの例 |
|---|---|---|
xmlns | 「このコードはSVGのルールで書かれています」という宣言 | xmlns="http://www.w3.org/2000/svg" |
width | 画面に表示するときの幅 | width="200"(200px) |
height | 画面に表示するときの高さ | height="120"(120px) |
viewBox | 絵の中のどの範囲を表示するか(次の見出しで解説) | viewBox="0 0 200 120" |
xmlnsの値はURLの形をしていますが、ネットに接続して何かを読み込むわけではなく、決まった文字列をそのまま書くだけです。
.svgファイルとして保存するSVGにはxmlnsが必要で、HTMLの中に直接書くSVGでは省略できます(MDN「<svg>」)。
迷ったら、毎回1行目にコピーして書いておけば問題ありません。
座標は左上が0、右と下に向かって増える
SVGで図形の位置を決めるときは、左上の角を(0, 0)として、右に行くほどx、下に行くほどyが大きくなる座標を使います。
座標とは、方眼紙のマス目のように「横に何マス、縦に何マス」で場所を表す数値のことです。
学校の数学のグラフはyが上に向かって増えますが、SVGではyが下に向かって増える点に注意しましょう(MDN「位置指定」)。
たとえば最初のコードの<circle cx="100" cy="60" ...>は、「左上から右に100、下に60の位置を中心に円を描く」という意味になります。
座標の数値にはpxのような単位を付けず、数字だけを書きます。
viewBoxは「絵のどの範囲を表示するか」
viewBoxは、絵を描いている座標のうち、どの範囲を切り取って表示するかを決める属性です。
値はviewBox="0 0 100 100"のように4つの数値を並べて書き、順に「左上のx」「左上のy」「範囲の幅」「範囲の高さ」を表します(MDN「viewBox」)。
切り取った範囲は、widthとheightで決めた表示サイズにぴったり合うように拡大・縮小されます。
次のコードは、まったく同じ円を、viewBoxとwidth・heightの組み合わせだけ変えて3回表示する例です。
<!-- 見本A:100×100の範囲を、100×100で表示 -->
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100">
<circle cx="50" cy="50" r="40" fill="#FFBD07"/>
</svg>
<!-- 見本B:100×100の範囲を、200×200で表示 -->
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" viewBox="0 0 100 100">
<circle cx="50" cy="50" r="40" fill="#FFBD07"/>
</svg>
<!-- 見本C:左上の50×50の範囲だけを、100×100で表示 -->
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 50 50">
<circle cx="50" cy="50" r="40" fill="#FFBD07"/>
</svg>
<!--と-->で囲んだ部分は「コメント」と呼ばれるメモ書きで、画面には表示されません。
※点線はSVGの表示範囲の目安として、この見本にだけ付けています
上のコードを表示した結果が、見本A・見本B・見本Cです。
見本Aと見本Bを比べると、円の座標は同じでも、widthとheightを2倍にすると絵全体が2倍に拡大されるのが分かります。
見本Cは、viewBoxの幅と高さを半分にしたことで、カメラでズームしたように左上の一部だけが大きく表示されています。
アイコンやロゴのSVGでは、viewBoxは「絵を描いた方眼紙の大きさ」、width・heightは「画面に表示する大きさ」と考えておけば、ほとんどの場合は読み解けます。
SVGの基本図形をコードで描いてみよう
ここからは、SVGでよく使う5つの図形(rect・circle・line・text・path)の書き方を、コードと表示結果を並べて見ていきます。
どの例も、<svg>の中に入れる図形のタグだけを変えています。
rect:四角形を描く
<rect>は四角形(rectangle=長方形)を描くタグで、左上の角の位置と、幅・高さを指定します。
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="100" viewBox="0 0 200 100">
<rect x="10" y="20" width="80" height="60" fill="#FFBD07"/>
<rect x="110" y="20" width="80" height="60" rx="12" fill="#FFBD07"/>
</svg>
| 属性 | 意味 |
|---|---|
x・y | 四角形の左上の角の位置 |
width・height | 四角形の幅と高さ |
rx・ry | 角を丸くするときの半径(片方だけ書くと、もう片方も同じ値になる) |
rxの数値を大きくするほど角の丸みが大きくなり、ボタンのような形も描けます(MDN「基本図形」)。
circle:円を描く
<circle>は円を描くタグで、四角形と違って「中心の位置」と「半径」で指定します。
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="100" viewBox="0 0 200 100">
<circle cx="50" cy="50" r="40" fill="#FFBD07"/>
<circle cx="150" cy="50" r="20" fill="#FFBD07"/>
</svg>
cx・cyが円の中心の位置、rが半径(中心から円の線までの長さ)です。
半径を指定するので、r="40"の円の直径(端から端までの長さ)は80になる点に気をつけましょう。
line:直線を描く
<line>は2つの点を結ぶ直線を描くタグで、始まりの点と終わりの点の座標を指定します。
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="100" viewBox="0 0 200 100">
<line x1="20" y1="80" x2="180" y2="20" stroke="#3A332A" stroke-width="4"/>
</svg>
x1・y1が始まりの点、x2・y2が終わりの点の座標です。
線には面がないので、線の色を指定するstrokeを書かないと、何も表示されません(stroke-widthは線の太さです)。
text:文字を描く
<text>はSVGの中に文字を書くタグで、開始タグと終了タグの間に表示したい文字を入れます。
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="100" viewBox="0 0 200 100">
<line x1="0" y1="60" x2="200" y2="60" stroke="#E7E1D3" stroke-width="2"/>
<text x="20" y="60" font-size="32" font-family="sans-serif" fill="#3A332A">Hello</text>
</svg>
x・yは文字の左上ではなく、文字が乗る線(ベースライン)の始まりの位置を表します(MDN「<text>」)。
ベースラインとは、アルファベットの「H」や「x」の下端がそろう、文字の土台になる線のことです。
そのためy="0"にすると、文字のほとんどが表示範囲の上にはみ出して見えなくなります。
font-sizeは文字の大きさ、font-familyは書体、fillは文字の色です。
path:自由な形を描く
<path>は、d属性に「ペンをどう動かすか」を書いて、自由な形を描くタグです。
デザインツールから書き出したSVGのアイコンやロゴは、ほとんどがこのpathでできています。
次のコードは、3つの点を直線で結んで三角形を描く例です。
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="100" viewBox="0 0 200 100">
<path d="M 100 10 L 170 90 L 30 90 Z" fill="#FFBD07" stroke="#3A332A" stroke-width="3"/>
</svg>
dの中身は、アルファベット1文字の「コマンド」と、その後に続く座標の組み合わせです。
| コマンド | 意味 | 上のコードでの動き |
|---|---|---|
M x y | ペンを持ち上げて(x, y)に移動する(Move to) | M 100 10:上の頂点からスタート |
L x y | 今の位置から(x, y)まで直線を引く(Line to) | L 170 90:右下へ、L 30 90:左下へ |
H x・V y | 横(H)または縦(V)にまっすぐ線を引く | (この例では使っていない) |
Z | スタートの点まで線を引いて形を閉じる | Z:上の頂点に戻って三角形が完成 |
大文字のコマンドは左上(0, 0)からの位置、小文字のコマンド(mやl)は今のペンの位置からどれだけ動くかを表します(MDN「パス」)。
pathには曲線を描くコマンド(CやQ、Aなど)もありますが、曲線の数値は手で書くより、デザインツールで描いて書き出すのが一般的です。
ツールが書き出したpathの長い数字は読めなくても問題なく、「ここで1つの形を描いている」と分かれば十分です。
図形を組み合わせて1枚の絵にする
ここまでの5つの図形を組み合わせると、簡単なイラストが描けます。
次のコードは、家と太陽と地面を描いた例です。
<svg xmlns="http://www.w3.org/2000/svg" width="240" height="160" viewBox="0 0 240 160">
<circle cx="200" cy="36" r="20" fill="#FFBD07"/>
<line x1="0" y1="140" x2="240" y2="140" stroke="#3A332A" stroke-width="3"/>
<rect x="50" y="80" width="100" height="60" fill="#FFDF85" stroke="#3A332A" stroke-width="3"/>
<path d="M 40 80 L 100 30 L 160 80 Z" fill="#7A5200"/>
<rect x="88" y="104" width="24" height="36" fill="#FFFFFF" stroke="#3A332A" stroke-width="3"/>
<text x="10" y="30" font-size="20" font-family="sans-serif" fill="#3A332A">HOME</text>
</svg>
SVGでは、コードの後に書いた図形ほど上に重なって描かれます(MDN「始めましょう」)。
このコードでも、壁の<rect>より後にドアの<rect>を書いているので、ドアが壁の上に表示されています。
なお、fill(塗りの色)やstroke(線の色)は色を指定する属性で、詳しい使い方はシリーズの8回目で扱います。
手で書いてブラウザで確かめる手順
コードは読むだけより、数値を書き換えて表示がどう変わるかを見るほうがずっと早く身につきます。
特別なソフトは必要なく、テキストエディタとブラウザがあれば次の手順で試せます。
- テキストエディタを開き、新しいファイルを作る。
Visual Studio Codeのようなコード用のエディタがおすすめです。
Macのテキストエディットを使う場合は、「フォーマット → 標準テキストにする」を選んでから書きます(Appleサポート「Macのテキストエディットで書類を作成する/開く/変換する」)。 - この記事のコードをどれか1つ貼り付ける。
1行目のxmlnsは消さずに残しておきます。 practice.svgのように、拡張子を.svgにして保存する。
保存後、ファイル名の最後が.txtなどになっていないかを確認しましょう。- 保存したファイルを、ChromeやSafariなどのブラウザのウィンドウにドラッグ&ドロップして表示する。
- エディタに戻って数値を1つだけ書き換えて保存し、ブラウザを再読み込みして変化を確かめる。
たとえば<circle>のrを40から20に変えると、円が小さくなるのが分かります。
1回に変える数値を1つにしておくと、「どの数値が何を決めているか」が確実に分かります。
実践のポイント
SVGのコードを手で書くときに起こりやすい間違いと、よくある疑問をまとめます。
注意点・よくある間違い
- 図形のタグを
/>で閉じ忘れる。
SVGはHTMLより書き方に厳しく、.svgファイルでは閉じ忘れが1か所あるだけで絵が表示されず、エラーの表示になることがあります。
中身のないタグは<rect ... />のように/>で閉じ、<text>のように中身があるタグは</text>で閉じましょう。 - 属性の値を
"(ダブルクォーテーション)で囲み忘れる。width=80ではなくwidth="80"のように、値は必ず引用符で囲みます。 - .svgファイルに
xmlnsを書き忘れる。
ブラウザがSVGだと認識できず、絵ではなくコードの文字が表示されることがあります。 <line>にstrokeを付け忘れて、線が見えない。
線は色を指定しないと表示されないので、strokeとstroke-widthをセットで書きましょう。- yの向きを逆に考えてしまう。
SVGではyの値が大きいほど下に表示されるので、図形を上に動かしたいときはyを小さくします。
よくある質問
- Q. viewBoxとwidth・heightは、どう違うの?
A. viewBoxは「絵の座標のどの範囲を見せるか」、width・heightは「その範囲を画面に何pxで表示するか」です。
viewBoxを書いておけば、width・heightを変えても絵全体が同じ比率で拡大・縮小されます。 - Q. デザインツールで書き出したSVGのpathの数字が長すぎて読めません。
A. 読めなくて問題ありません。
曲線を含む形は、ツールが細かい数値を自動で書き出しています。
コードを読むときは、タグの種類とviewBox・width・heightを確認できれば十分です。 - Q. 座標に小数やマイナスの数値は使える?
A. 使えます。cx="12.5"のような小数も書けますし、マイナスの座標に置いた図形は表示範囲の外(左や上)にはみ出します。
まとめ
SVGのコードは、svg要素(xmlns・width・height・viewBox)という画用紙の中に、rect・circle・line・text・pathといった図形のタグを並べたものです。
座標は左上が(0, 0)でyは下に向かって増え、viewBoxは「どの範囲を見せるか」、width・heightは「何pxで表示するか」を決めます。
まずはこの記事の家のイラストのコードをpractice.svgとして保存し、ブラウザで開いて、太陽のcxや屋根のpathの数値を1つずつ書き換えてみてください。
次の回では、fillとstrokeを使ってSVGの色をCSSで変える方法を扱います。


























