HTMLとCSSでSVGを使うためのメモ


Qiita初投稿です。

2014年にフリーランスとなってからというもの、なかなか勉強の時間がとれず、おざなりになってしまっている技術がいくつかあります……
その中でもSVGの扱い方について、簡単にではありますが調べたのでメモしておきます。
昨日までの自分に教えるような気持ちで書きます！

## まず、SVGは使えるのか？

### ブラウザ対応状況

[Can I use\.\.\. Support tables for HTML5, CSS3, etc](http://caniuse.com/#search=svg)

だいたい大丈夫です（2016/07/27現在）
IEも9以降であれば表示はできるっぽいです。

### メリット

* 拡大・縮小に強い（きれい）
* 軽い
* 使い方によってはCSSで装飾したり、アニメーションさせることも可能
* アクセシビリティ上も良いことがある（まだあまり調べてない）

### デメリット

* 写真やイラスト等には向かない（どんな画像かによる。これまでGIFやPNGで書き出していたタイプの画像が向いていそう）
* 実装状況にバラつきがある（表示自体は問題ないが、インタラクションをつけようとすると問題があったりするみたい）

## 使い方

### img要素で読み込む

```html:
<img src="test.svg">
```

### background-imageから読み込む

```html:
<div class="test"></div>
```

```css:
.test{
  background-image: url("test.svg");
}
```

### HTML中に直接SVGのコードを記述

```html:
<svg id="レイヤー_1" data-name="レイヤー 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
  <defs>
   <style>.cls-1{fill:#ccc;}</style>
  </defs>
  <title>名称未設定-1</title>
  <circle class="cls-1" cx="50" cy="50" r="50"/>
</svg>
```

_SVGはXMLなので、空要素は最後に「/」をつけること！（さもないと正常に表示されません）_

### object要素で読み込む

```html:
<object type="image/svg+xml" data="test.svg" width="100" height="100"></object>
```

iframeみたいな感じになるらしい。

## CSSでの装飾

↑ の3番、HTMLにSVGタグで埋め込む場合、CSSでいろいろ装飾できます。
いつも使ってるCSSのプロパティと全然違うので、最初は「？？？」となりますが、たぶん慣れます。
たとえば、背景色を変える場合普通は`background-color`ですが、SVGに対しての場合は`fill`です。

### 使えそうなプロパティ

#### 塗りつぶし

* fill … 塗りつぶし。transparent もOK
* fill-opacity … 透明度。0〜1

#### 線

* stroke … 線色
* stroke-width … 線幅。px は不要。小数点OK
* stroke-dasharray … 点線の周期。2 4 とか 2 2 1 2 とか
* stroke-dashoffset … 点線の開始位置をずらす

### 書き方

```html:
<svg id="test" xmlns="http://www.w3.org/2000/svg">
  <circle class="icon" cx="50" cy="50" r="50"/>
</svg>
```

この場合

```css:
#test{
  fill: red;
}
```

でも

```css:
.icon{
  fill: red;
}
```

でもOK。

#### グラデーション

グラデーションはCSSのみでは無理。

1. SVG側に`linearGradient`要素をつくる ※IDでなくてはだめ
2. linearGradient要素内に更に`stop`要素を作り、グラデーションの色切り替えポイントを指定
3. CSSでは、まずSVG要素のfillに、linearGradient要素のIDをurl(〜)で指定
4. stop要素のカラーをそれぞれ指定

```html:
<svg id="test" xmlns="http://www.w3.org/2000/svg">
  <defs>
    <linearGradient id="gradient1">
      <stop class="stop1" offset="0%"/>
      <stop class="stop2" offset="100%"/>
    </linearGradient>
  </defs>
  <circle class="icon" cx="50" cy="50" r="50"/>
</svg>
```

```css:
#test{
  fill: url("#gradient1");
}
.stop1{
  stop-color: red;
}
.stop2{
  stop-color: black;
  stop-opacity: 0;
}
```

[Gradients \- SVG \| MDN](https://developer.mozilla.org/ja/docs/Web/SVG/Tutorial/Gradients)




## とりあえずの現実的な使い方

### 1. SVGスプライト

1. Illustratorでアートボードをひとつ作成
2. スプライトにしたい画像をテキトウに貼り付ける（すべて同じレイヤー）
3. サブレイヤー名をID名にする
4. 全画像の位置を重ねる
3. SVGで別名保存
4. テキストエディタで開き、svg要素以下をdefs要素でラップ

すると、

```html:
<svg class="icon">
  <use xlink:href="test.svg#icon-home3"/>
</svg>
```

```css:
.icon{
  fill: red;
}
```

こういう感じで簡単にSVG画像を表示できるSVGスプライトが完成します。

[IllustratorとIcoMoonでSVGスプライトのラクラク設定！ \| Webクリエイターボックス](http://www.webcreatorbox.com/tech/illustrator-icomoon-svg-sprite/)
[IllustratorでSVGスプライトをつくってみよう – Design Report – デザインレポート](http://glitter-style.jp/labo/web-resource/make-svg-sprites2/)

CSSスプライトのほうが便利な場面もあると思うので、そのあたりは臨機応変に。

### 2. アニメーションをつける

[サンプル](https://jsfiddle.net/m4btjfx1/1/)

塗りつぶしや線を利用してアニメーションをつけるとオシャレ。