SVGに関する基礎知識
文章構造と構成要素
SVGには専用の構成要素タグがあり、タグを観ることでその図形がどのような形状のものか判別できるようになっています。 この構成要素を知っていれば編集の際効率よく作業を進めることができます。
基本となる要素名を下記に
<svg> | SVG要素。このタグの中に下記の各要素を含んで一つのSVGデータとする。 |
<defs> | 「非参照要素」を表す。フィルターやクリッピングパス、スプライトで使用する図形はこのタグ内に入れておいて使いまわし・再利用することができる。 |
<g> | 「グループ」を表す。 |
<symbol> | 参照用図形。この要素内のものは単体では決して表示されることが無く、use要素によってのみ描画される。 |
<title> | img要素のtitle属性と同じ。ツールチップ表示もされる。 |
<desc> | 「Description=説明」svg要素全体として、その要素がどのような意味をもつ要素なのか説明できる。ニュアンス的にはimg要素のalt属性。(※ただしテキストの代替表示をするものではない) |
SVGは「xml文章」というだけあって、このパーツが「何」かを適切にブラウザへ伝えることができます。
タグによって説明された意味は画像のalt属性より強い意味を持つ(と書いてありましたがSEO的にどこまでの差があるかは何とも・・) 現在ではalt属性をしっかり読みこんでくれるようになってはいるみたいなので、もしかすると大差は無いかもしれませんが、アウトライナーなどで要素を読みとっての検証では、SVGをh要素に用いた場合内の説明(desc,titleどちらでも)を適切に読みとってくれました。(画像のalt属性だとNo titleと表示される)
<line / > | 「直線」要素を表す | |
<polyline /> | 「折れ線」要素を表す | |
<rect /> | 「四角形」要素を表す | |
<polygon /> | 「多角形」を表す(四角形以外はこの要素で作成) | |
<circle /> | 「正円」要素を表す | |
<ellipse /> | 「楕円」要素を表す | |
<path /> | 「パス」を表す。曲線はペジェ曲線で作成可能で、ペンツールと同様の考え方。線を閉じれば面(塗りのある図形)としても作成可能 | |
<text> | 「テキスト」を表す。Illustratorなどでアウトライン化せずに出力したテキストなどもこの要素で出力される。 |
これらの要素の記述法を知れば Illustrator等で作成したSVGデータにテキストエディタから図形やパスを追記することもできます。
使いたいパーツ構成に応じたグループ分けを行う
SVGは「要素単位」で使用できます。 使いたい要素毎に個別のidを指定し、xlink:hrefで参照することで何度でもいくつでも使用できる
<svg> <defs> <path id="p1" d="..."> <rect id="r1" x=".." y=".." width=".." height=".."> <rect id="r2" x=".." y=".." width=".." height=".."> </defs> </svg> <!-- --> <svg><use xlink:href="#p1" /></svg> <svg><use xlink:href="#r1" /></svg> <svg><use xlink:href="#r2" /></svg> <svg><use xlink:href="#p1" /></svg> <svg><use xlink:href="#p1" /></svg>
同じ要素を複数参照すると「idが重複するのでは?」と考えられるでしょう。しかし、use要素は内包物を完全にコピーするものではなく、内包するものをすべてuseという一つの新しい要素として置き換えるようなものと考えていただければ良いと思います。
use要素による効果は、あたかも参照先の要素の内容が DOM 木において — その use 要素を親とする別個の非公開木として,かつ use 要素のすべての先祖がその木の先祖になるように — 末端まで複製されたかのようにふるまう。 複製された DOM 木は非公開なので、 SVG 文書オブジェクトモデル( DOM )においては use 要素とその属性が存在するだけであり,参照先の要素の内容が use 要素の子としては現れることはない。
※文章構造-SVG1.1より
http://www.hcn.zaq.ne.jp/___/SVG11-2nd/struct.html#UseElement
試しにuse要素の親(svg要素)にclass等を付与し、.svg1 #p1{…}といった指定を行ってもスタイルは反映されません。use要素内にそのidを持つ子要素が無いと判定される為です。
上記のようなパーツをまとめたスプライトを一つのパーツとして利用することもできます。
<svg> <defs> <g id="parts1"> <path id="p1" d="..."> <rect id="r1" x=".." y=".." width=".." height=".."> <rect id="r2" x=".." y=".." width=".." height=".."> </g> </defs> </svg> <!-- --> <svg> <use xlink:href="#parts1" /> //#p1,#r,#r2がすべて表示される </svg> <svg><use xlink:href="#r1" /></svg> //同時にg要素内のパーツを個別で利用することもできる
通常の書き出しではスプライト用の<defs>(参照用要素)タグは使用されません
スプライトとして使用するパーツを「すべて」<defs>タグで囲います。
<defs>タグに入れた要素は表示されることはありませんが、SVG要素そのものは「viewBox」という「大きさ」を持っています。 スプライトで使用する際はSVG要素そのものをdisplay:noneなどで非表示にしておきます。(svg 要素に記述)
使用時の注意点
Safariや特定のOSでの閲覧時にていくつかの不具合があります。
(※2014年8月現在の段階)
- SVGにwidth、heightのサイズ指定をしなかった場合、指定しなかったプロパティに(use要素のviewBox指定を無視して)元SVGのviewBoxのサイズが適用される(おそらくバグ)という現象があります。
→現状では都度width、height両方の指定を行っておくべき。 - SVGをaタグで囲った際、SVGにdisplya:blockを指定しておかなければリンクエリアが1pxになるという現象を確認。
→現状ではリンクに用いる場合、SVGをaタグで囲う際はdisplya:block(+width,height:100%)必須 - iOSにおいて、SVGに対するスタイル指定が一部反映されないケースがある(どのように処理するかの解釈が違っているのかもしれない)。
Ex. SVGに対してPaddingを指定した場合、他のブラウザではアートワークが縮小されるがiOSでは縮小されず、位置がずれる。
※Androidは実機無しの為検証していません。情報があればお寄せいただけると幸いです。 - モバイルでstroke-dashoffsetのtransitionが効かないケース有。
iPadでは正確に動作するものの、iPhoneでは動作しないケースがあり。。 - pjaxを用いる際、SVGのtitle要素を使用しているとページタイトルがSVGのタイトル要素内の内容に置き替る。(ほとんどのpjaxプラグインが「ページ内の最後のtitle要素」を取得しページタイトルを書き換える仕様)
→pjaxサイトではSVGにtitle要素を使わない方が良い。
Comments
[…] SVG に関する基礎知識 | Design Report デザインレポート […]