CSS
SVG

SVGをuseタグで使いまわす

この記事は J2complexed Advent Calendar 2017 の15日目の記事です。

SVGを表示するのには、さまざまな書き方がありますね。
1. インライン
2. imgタグでsvg画像ファイル読み込み
3. cssでsvg画像ファイル読み込み
4. objectタグ

1.の派生、useタグを使ったインラインの書き方が便利なので、まとめる。
(もういろんなところでまとまってる今更話だけど、後半の話とかわかりやすい記事がぱっと見つけられなかったので、自分まとめ用に)

同じ画像いろんなところで使いたい。

svg画像をimgタグなどで読み込むと、これまでの普通の画像と同じく、使い回すには便利。
が、アニメーションさせたり色変えたり、svgの良いところがあんまり活かされない。
でも、インラインでコピペしまくるのは、コードが大変なことになるのでやりたくない。
そんなときのuse

useタグ基本の使い方

呼び出し元

ページのどこかで、svgの元コードを読み込んでおく。
ここでは表示しない、あくまで呼び出し元なので、symbolタグでくくっておく。symbolタグは、その場で表示するのではなく、あとでuseタグで呼び出す用として定義だけをするものです。

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" class="svg-symbol">
  <symbol viewbox="0 0 512 512" id="reindeer">
   <path class="st0" d="M441.1,0c-10.1,0-18.3,8.2-18.3,18.3c0,23.2-1.2,41.5-3.7,55.1c-1.8,10.2-4.3,17.8-7.1,23.2
        c-2.1,4-4.2,6.8-6.5,9c-3.5,3.2-7.6,5.5-14.1,7.3c-6.4,1.7-15.1,2.6-26,2.6c-16.9,0-35.8,0-55.7,0c-5.8,0-8.5-1.1-10-2.1 ....> <!-- 略 -->  </symbol>
</svg>

symbolタグに、viewbox属性でカンバスサイズを入れることができます。svgタグ内にいくつもsymbolを格納できるので、カンバスサイズはsymbol側にもたせた方が取り回ししやすいです。
id属性で呼び出すときの名前をつけておきます。

呼び出す方

<svg viewBox="0 0 512 512" class="reindeer"><use xlink:href="#reindeer"></use></svg>

サイズ変え放題!色変え放題!短い!はっぴー

.reindeer {
  width: 300px;
  fill: #aaa;
}

スクリーンショット 2017-12-12 12.23.39.png

パーツごとに色変えたい

色変え放題、といったものの、上の書き方だと、全体の色を1色にすることしかできません。
モノクロのロゴを、ここでは本来のカラーにしたい、とか、全体の色じゃなくパーツごとに色変えたい欲は頻繁に起こるものです。

呼び出し元

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" class="svg-symbol">
  <symbol viewbox="0 0 512 512" id="reindeer">
    <g id="face">
    <path class="st0" d="M441.1,0c-10.1,0-18.3,8.2-18.3,18.3c0,23.2-1.2,41.5-3.7,55.1c-1.8,10.2-4.3,17.8-7.1,23.2
        c-2.1,4-4.2,6.8-6.5,9c-3.5,3.2-7.6,5.5-14.1,7.3c-6.4,1.7-15.1,2.6-26,2.6c-16.9,0-35.8,0-55.7,0c-5.8,0-8.5-1.1-10-2.1
        c-1.1-0.7-1.9-1.5-2.9-2.9c-1.4-2.2-2.9-6.3-3.7-12c-0.8-5.6-1.1-12.6-1.1-20c0-5.3,0.1-10.8,0.1-16.4c0-10.1-8.2-18.3-18.3-18.3
        c-10.1,0-18.3,8.2-18.3,18.3c0,5.1-0.1,10.6-0.1,16.4c0,7.2,0.2,14.8,1.1,22.5c0.6,4.8,1.6,9.7,3,14.5c-13.6,0-27.4,0-41.4,0
        c-5.8,0-8.5-1.1-10-2.1c-1.1-0.7-1.9-1.5-2.9-2.9c-1.4-2.2-2.9-6.3-3.7-12c-0.8-5.6-1.1-12.6-1.1-20c0-5.3,0.1-10.8,0.1-16.4
        c0-10.1-8.2-18.3-18.3-18.3s-18.3,8.2-18.3,18.3c0,5.1-0.1,10.6-0.1,16.4c0,7.2,0.2,14.8,1.1,22.5c0.6,4.8,1.6,9.7,3,14.5
        c-3.2,0-6.4,0-9.6,0c-17.2,0-29.6-2.5-38.4-6.3c-6.6-2.8-11.3-6.3-15.1-10.5c-5.7-6.3-9.7-14.8-12.3-26.4
        c-2.6-11.6-3.6-25.9-3.6-42c0-10.1-8.2-18.3-18.3-18.3c-10.1,0-18.3,8.2-18.3,18.3c0,15.5,0.7,30.5,3.4,44.7
        c2,10.6,5,20.9,9.8,30.4c7.1,14.3,18.8,26.9,34.5,34.9c15.8,8,35,11.8,58.2,11.8c51.8,0,103.5,0,148.9,0v65.7
        c-0.3,24.4-56.6,25-114.6,32C92.2,261.9,58.1,296.2,75.3,344.8c17,48.2,62.3,59,101.6,59s57.1,0.7,62.3,19.7
        c9.8,36.1,23,88.5,23,88.5h183.6l-65.6-213.1c0,0,49.2-3.3,59-26.2c9.8-22.9-16.3-36.6-45.3-30.5c-32.9,6.9-49.9-4.6-49.9-27.4
        v-0.3V152c7.5,0,14.6,0,21.5,0c15,0,28.6-1.2,41.3-5.6c9.5-3.3,18.4-8.5,25.7-16c5.4-5.6,9.9-12.2,13.4-19.6
        c5.2-11.1,8.5-24,10.6-39.1c2.1-15.1,3-32.7,3-53.4C459.4,8.2,451.2,0,441.1,0z M257.5,307.7c-8,0-14.5-6.5-14.5-14.5
        c0-8,6.5-14.5,14.5-14.5c8,0,14.5,6.5,14.5,14.5C272,301.2,265.5,307.7,257.5,307.7z"/>
</g>
<g id="nose">
    <circle class="st0" cx="77" cy="303" r="17.5"/>
</g>
  </symbol>
</svg>

さっきのコードを、色変えたいパーツごとにgタグでくくる。groupのgです。
groupにid属性で名前をつけておく。

呼び出す方

ここも変わらずuse、だけど、先ほどgタグで括ったパーツごとに呼び出します。

<svg viewBox="0 0 512 512" class="rudolph"><use xlink:href="#reindeer"></use>
  <use class="face" xlink:href="#face"></use>
  <use class="nose" xlink:href="#nose"></use>
</svg>

それを、パーツごとに色付け

.rudolph {
  width: 250px;
  .face {
    fill: #472807;
  }
  .nose {
    fill: #FB0D1B;
  }
}

スクリーンショット 2017-12-12 12.25.54.png
ルドルフに忍び寄る影、みたいになった

パーツの要素がばらばらの位置にあっても、色同じでOKなら、ひとつのgタグの中に突っ込めるので、色数が多くならなければスッキリかけます。
ロゴとか、ここでは白ベースでこっちでは黒ベース(そして濃淡がいろいろ)とか、ヘッダーではカラーだがフッターではモノクロだ!とかよくあるので、そんなときに便利かなっておもいます。