SVGの扱い方を心得よ

巷で人気のSVGについてwebデザインやってる人が色々調査したことかきます :wink: :wink: :wink:

## テキストエディタで開いて無駄なものは排除せよ
AdobeのソフトとかFigmaとかで書き出したSVGはとにかく無駄なものが多いのでテキストエディタで開いて編集します。

以下、[Google Material Icons](https://material.io/resources/icons/)の`favorite`をそれぞれのツールで保存&コピーしたものをテキストエディタで開いたものです。
※ わかりやすくするために改行・インデントいれてますが、容量は改行・スペースを抜いた状態です

**Adobe XD - 416バイト**

```xml
<svg id="_24px" data-name="24px" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
  <path id="パス_605" data-name="パス 605" d="M0,0H24V24H0Z" fill="none"/>
  <path id="パス_606" data-name="パス 606" d="M12,21.35l-1.45-1.32C5.4,15.36,2,12.28,2,8.5A5.447,5.447,0,0,1,7.5,3,5.988,5.988,0,0,1,12,5.09,5.988,5.988,0,0,1,16.5,3,5.447,5.447,0,0,1,22,8.5c0,3.78-3.4,6.86-8.55,11.54Z"/>
</svg>
```

**Adobe Illustrator - 605バイト**

```xml
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.6, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
<svg version="1.1" id="レイヤー_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
	 y="0px" viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" xml:space="preserve">
<style type="text/css">
	.st0{fill:none;}
</style>
<path class="st0" d="M0,0h24v24H0V0z"/>
<path d="M12,21.4L10.6,20C5.4,15.4,2,12.3,2,8.5C2,5.4,4.4,3,7.5,3c1.7,0,3.4,0.8,4.5,2.1C13.1,3.8,14.8,3,16.5,3
	C19.6,3,22,5.4,22,8.5c0,3.8-3.4,6.9-8.6,11.5L12,21.4z"/>
</svg>
```

**Figma - 308バイト**

```xml
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
  <path d="M12 21.35L10.55 20.03C5.4 15.36 2 12.28 2 8.5C2 5.42 4.42 3 7.5 3C9.24 3 10.91 3.81 12 5.09C13.09 3.81 14.76 3 16.5 3C19.58 3 22 5.42 22 8.5C22 12.28 18.6 15.36 13.45 20.04L12 21.35Z" fill="black"/>
</svg>
```

**Google Material Icons - 312バイト**

```xml
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
  <path d="M0 0h24v24H0z" fill="none"/>
  <path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"/>
</svg>
```
いろんなコードがありますが、どれもこれもいろいろ追加しているので私的には下記コードが一番いいかなと思ってます。


**わたしのかんがえたさいきょうのSVG - 252バイト**

```xml
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
  <path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"/>
</svg>
```

1. FigmaからSVGをコピー
2. エディタに貼り付け
3. width, height, fillを抜く
4. 改行・スペース消して保存

又は

1. Google Material IconsでSVGダウンロード
2. エディタで開く
3. width, height, fill, 1つめのpathを抜く

このフローで軽量SVGが完成します。
（下の方法の方が軽量ですがSVGはMaterial Iconだけではないので2つ記載しました）

1つめのpathは24px*24pxの四角のpathなので、`viewBox`が有る限り、削除して大丈夫です。

```xml
<svg xmlns="http://www.w3.org/2000/svg" viewBox="">
<path d=""/>
</svg>
```

これだけあればだいじょうぶ。`<g>`も`<style>`もいらないです。

## pngとの使い分けを意識せよ
SVGはいつでもどこでも軽くて可変がきいてめっちゃいい！
みたいなのは幻想です。

SVGは上でも見た通り、テキストです。
テキストが増えると容量が増えて重くなります。

カラーが多いもの、複雑なパスなどはpngの方が容量が軽くて、用途に適していることが多々あります。
これはpngかな？SVGかな？と迷ったら検証するのが一番です。

例えばこの画像

![Vorderrhein.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/500709/aa868a05-1c47-fd87-3408-d357ebacae33.png)


pngだと85KB、SVGだとどんだけ軽量をがんばっても200KBはいっちゃいます。

**使い分け、めっちゃ、大事。**



## 複合パスを使用せよ
SVGは<path>というタグが増えるだけでSVGの容量が増えます。
ので、1色だけしか使用しないようなロゴやアイコンについては複合パスを使用しましょう。

複合パスはAdobe Illustratorで使用できます。
グループ化と複合パスを間違える人がいますが、グループ化だと`<g>`タグがはいるのでエディタで確認してください。

[Google Material Icons](https://material.io/resources/icons/)の`camera`を、複合パスでないものと複合パスのものを比較します。

**複合パスでないもの - 556バイト**

```xml
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
  <path d="M9.4,10.5l4.8-8.3C13.5,2.1,12.8,2,12,2C9.6,2,7.4,2.8,5.7,4.2l3.7,6.4C9.3,10.6,9.4,10.5,9.4,10.5z"/>
  <path d="M21.5,9c-0.9-2.9-3.1-5.3-6-6.3L11.9,9H21.5z"/><path d="M21.8,10h-7.5l0.3,0.5l4.8,8.2C21,17,22,14.6,22,12C22,11.3,21.9,10.6,21.8,10z"/>
  <path d="M8.5,12L4.6,5.2C3,7,2,9.4,2,12c0,0.7,0.1,1.4,0.2,2h7.5L8.5,12z"/><path d="M2.5,15c0.9,2.9,3.2,5.3,6,6.3l3.7-6.3H2.5z"/>
  <path d="M13.7,15l-3.9,6.8c0.7,0.1,1.4,0.2,2.2,0.2c2.4,0,4.6-0.9,6.3-2.2l-3.7-6.4C14.7,13.4,13.7,15,13.7,15z"/>
</svg>
```

**複合パス - 489バイト**

```xml
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
  <path d="M9.4 10.5l4.77-8.26C13.47 2.09 12.75 2 12 2c-2.4 0-4.6.85-6.32 2.25l3.66 6.35.06-.1zM21.54 9c-.92-2.92-3.15-5.26-6-6.34L11.88 9h9.66zm.26 1h-7.49l.29.5 4.76 8.25C21 16.97 22 14.61 22 12c0-.69-.07-1.35-.2-2zM8.54 12l-3.9-6.75C3.01 7.03 2 9.39 2 12c0 .69.07 1.35.2 2h7.49l-1.15-2zm-6.08 3c.92 2.92 3.15 5.26 6 6.34L12.12 15H2.46zm11.27 0l-3.9 6.76c.7.15 1.42.24 2.17.24 2.4 0 4.6-.85 6.32-2.25l-3.66-6.35-.93 1.6z"/>
</svg>
```

データの美しさも容量も圧倒的に変わります。

複合パスは複数のパスを1つのパスとしてまとめる機能なので、パスごとに色を変えるデータには適しません。



## 改行・スペースは削除せよ
改行とスペースって意外と容量食うんですよ〜〜〜〜〜
なので、邪魔な改行とスペースは消します。

上の複合パスだと、改行なしはこうなります。

```xml
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.4 10.5l4.77-8.26C13.47 2.09 12.75 2 12 2c-2.4 0-4.6.85-6.32 2.25l3.66 6.35.06-.1zM21.54 9c-.92-2.92-3.15-5.26-6-6.34L11.88 9h9.66zm.26 1h-7.49l.29.5 4.76 8.25C21 16.97 22 14.61 22 12c0-.69-.07-1.35-.2-2zM8.54 12l-3.9-6.75C3.01 7.03 2 9.39 2 12c0 .69.07 1.35.2 2h7.49l-1.15-2zm-6.08 3c.92 2.92 3.15 5.26 6 6.34L12.12 15H2.46zm11.27 0l-3.9 6.76c.7.15 1.42.24 2.17.24 2.4 0 4.6-.85 6.32-2.25l-3.66-6.35-.93 1.6z"/></svg>
```

ほかにもデータ内のスペース削除や文字の置き換えがありますがメンテコストがえぐいので省きます。


## 変化する予定の要素は未挿入を維持せよ
色やサイズなど変化すると思われる要素をSVGに入れるのは極力控えましょう。

CSSで簡単に色付けできます。
色付けの方法はググればでてくるので、応用として、複数のパスでなるSVGの色付けについて説明します。

```xml
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
  <path d="M9.4,10.5l4.8-8.3C13.5,2.1,12.8,2,12,2C9.6,2,7.4,2.8,5.7,4.2l3.7,6.4C9.3,10.6,9.4,10.5,9.4,10.5z"/>
  <path d="M21.5,9c-0.9-2.9-3.1-5.3-6-6.3L11.9,9H21.5z"/><path d="M21.8,10h-7.5l0.3,0.5l4.8,8.2C21,17,22,14.6,22,12C22,11.3,21.9,10.6,21.8,10z"/>
  <path d="M8.5,12L4.6,5.2C3,7,2,9.4,2,12c0,0.7,0.1,1.4,0.2,2h7.5L8.5,12z"/><path d="M2.5,15c0.9,2.9,3.2,5.3,6,6.3l3.7-6.3H2.5z"/>
  <path d="M13.7,15l-3.9,6.8c0.7,0.1,1.4,0.2,2.2,0.2c2.4,0,4.6-0.9,6.3-2.2l-3.7-6.4C14.7,13.4,13.7,15,13.7,15z"/>
</svg>
```

こんなコードがあって、一番上に赤、二番目に白、三番目に青、四番目に黄色をつけたいとします。

SVG内に色を入れると

```xml
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
  <path fill="red" d="M9.4,10.5l4.8-8.3C13.5,2.1,12.8,2,12,2C9.6,2,7.4,2.8,5.7,4.2l3.7,6.4C9.3,10.6,9.4,10.5,9.4,10.5z"/>
  <path fill="white" d="M21.5,9c-0.9-2.9-3.1-5.3-6-6.3L11.9,9H21.5z"/><path d="M21.8,10h-7.5l0.3,0.5l4.8,8.2C21,17,22,14.6,22,12C22,11.3,21.9,10.6,21.8,10z"/>
  <path fill="blue" d="M8.5,12L4.6,5.2C3,7,2,9.4,2,12c0,0.7,0.1,1.4,0.2,2h7.5L8.5,12z"/><path d="M2.5,15c0.9,2.9,3.2,5.3,6,6.3l3.7-6.3H2.5z"/>
  <path fill="yellow" d="M13.7,15l-3.9,6.8c0.7,0.1,1.4,0.2,2.2,0.2c2.4,0,4.6-0.9,6.3-2.2l-3.7-6.4C14.7,13.4,13.7,15,13.7,15z"/>
</svg>
```

こんなかんじで、CSSにすると

```css
svg path:nth-child(1) {
  fill: red;
}
svg path:nth-child(2) {
  fill: white;
}
svg path:nth-child(3) {
  fill: blue;
}
svg path:nth-child(4) {
  fill: yellow;
}
```

擬似クラスを使用して簡単に色付けすることができます。
テキストとしては多くなるので容量を比較するとSVGに直接書き込んだ方が良いと思う方も多いと思いますが、ここにHoverなどの擬似クラスを入れた場合に**管理が楽**になります。

---

最後までご覧いただきありがとうございました。

こんな感じの軽量化をいろいろ取り入れた、シンプルな自分のメディアをつくれるPurelistというサービスをリリースしました。
β版、US向けなので日本語入力時のバグ等まだ排除しきれてませんがよかったら触ってみてください。

[Purelist](https://purelist.com)