SVG画像をHTMLへ<svg>
タグとして設置すると
塗りのfillや、線のstrokeなどをCSSから変更することができ
オンマウスでの色変更にtransition
でアニメーションをつけるなど表現の幅が広がります。
しかし、地図などパスの形が複雑になると、SVGコードが座標の指定だけでエディタを埋め尽くす程度には長くなるため
どのようなケースでも気軽に導入しにくい一面もあります。
SVGスプライトならHTMLを簡略化できる
そこで、HTMLソースが冗長になるのを避ける有効な方法がuse
による参照を活用したSVGスプライトです。
このようなとても長いコードを
<svg xmlns="http://www.w3.org/2000/svg"> <symbol id="hoge" viewBox="0 0 4 4"> <path d="M417.1,227.8c-0.5-0.4-1.2-0.7-1.5-0.6c0,0-0.1,0-0.1,0c-0.2,0.1-0.1,0.4,0.8,1.1c0.2,0.2,0.6,0.3,0.8,0.3 ..." /> </symbol> <symbol id="fuga" viewBox="0 0 4 4"> <path d="M447.5,218.7c-0.2-0.7-1.1-1-1.8-1.1h0c-1.1-0.2-1.8-0.5-2.4-0.7c-0.3-0.1-0.5-0.2-0.7-0.2 ..." /> </symbol> </svg>
短くHTMLへ設置できます。
<svg> <use xlink:href="map.svg#hoge" /> <use xlink:href="map.svg#fuga" /> </svg>
ただ、このままだと
hogeとfugaそれぞれにCSSからスタイルを設定し、表示も崩れないよう担保できないため
いくつか属性が必要です。
IE11やEdgeにも対応した構成
結論からいくと、このようになります。
<svg xmlns="http://www.w3.org/2000/svg"> <symbol id="hoge" viewBox="0 0 4 4"> <path class="hoge-style" d="M417.1,227.8c-0.5-0.4-1.2-0.7-1.5-0.6c0,0-0.1,0-0.1,0c-0.2,0.1-0.1,0.4,0.8,1.1c0.2,0.2,0.6,0.3,0.8,0.3 ..."/> </symbol> <symbol id="fuga" viewBox="0 0 4 4"> < path class="fuga-style" d="M447.5,218.7c-0.2-0.7-1.1-1-1.8-1.1h0c-1.1-0.2-1.8-0.5-2.4-0.7c-0.3-0.1-0.5-0.2-0.7-0.2 ..."/> </symbol> </svg>
<svg viewBox="0 0 4 4" class="test"> <use class="hoge-style" xlink:href="dot.svg#hoge" /> <use class="fuga-style" xlink:href="dot.svg#fuga" /> </svg>
.test .hoge-style { fill: whitesmoke; transition: fill 250ms; } .test .fuga-style { fill: gray; transition: fill 250ms; } .test:hover .hoge-style { fill: white; } .test:hover .fuga-style { fill: cyan; }
ポイント
- SVG内の、
use
で呼び出したい単位をsymbol
で囲いid
を指定。 - HTMLに記述する
svg
タグにもviewBox
属性を記述。 - SVG内の
symbol
が持つpath
(またはそれに準ずるg
やcircle
やpolygon
など)と、HTMLに記述するuse
タグに同じclass
を付与。
symbol
の使用とviewBox
の指定は、IE11で表示を崩さないための対策です。
Chromeなどのモダンブラウザで、表示されたHTMLを開発者ツールを通して見てみるとsvg
タグ内へはuse
がclass
つきの状態で表示されており、その内部にclass
が付与されていないpath
が呼び出された状態で解釈されていることがわかります。
しかし、IE11ではsvg
タグ内にuse
は存在せず、symbol
内部のタグがSVGソース時のclass
が付与されている状態で解釈されています。
したがって、use
とSVG内のpash
両方にclass
を付与したところ
クロスブラウザでCSSによる制御に対応できることがわかりました。