SVGをuseタグで使いまわす


この記事は [J2complexed Advent Calendar 2017](https://qiita.com/advent-calendar/2017/j2complexed) の15日目の記事です。

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

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

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

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

```html
<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`属性で呼び出すときの名前をつけておきます。


### 呼び出す方

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

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

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

![スクリーンショット 2017-12-12 12.23.39.png](https://qiita-image-store.s3.amazonaws.com/0/78840/17bb881c-fb9c-a740-1b9d-28ff8617c5e8.png "スクリーンショット 2017-12-12 12.23.39.png")


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

### 呼び出し元
```html
<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`タグで括ったパーツごとに呼び出します。

```html
<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>
```

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

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

![スクリーンショット 2017-12-12 12.25.54.png](https://qiita-image-store.s3.amazonaws.com/0/78840/ebffc16f-f0b5-c3ce-1234-1a656929eea8.png "スクリーンショット 2017-12-12 12.25.54.png")
ルドルフに忍び寄る影、みたいになった

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