HTML
CSS
illustrator

IllustratorからhtmlにSVGアイコンを表示するまでの流れ

More than 1 year has passed since last update.

イラストレーターでアイコンを作成し、svgタグで出力するための流れを書いてみました。
今回のサンプルでは点数を5つ星で表示するようなものを作ります。
記事は長いですが、解説が多いだけです(頑張って画像も付けました)。実際に私が書くと5分もかからず終わるレベルです。

svg周りはブラウザによって挙動が異なるので注意しながら制作してください。(今回ハマりました)

Illustrator

Illustratorが無い方は(Illustratorは以上)まで飛んでください。

新規ドキュメント

サイズなどは後で調整するので適当で構いません。
Webで使用するのでカラーモードはRGBにしてください。(色はCSSで調整するのでIllustrator上はCMYKでも大丈夫だったりします)

01.png

隠れている設定があるので「詳細設定」をクリックします。

02.png

更に「詳細」をクリックすると新たに隠れているものが出てきます。環境によっては元から開いてあるかもしれません。
「プレビューモード」をピクセルにします。これをするとサイズの単位にpxが利用できます。
ドキュメント作成でキャンバスを作成します。

星を書く

スターツールを使い適当に星を書きます。
Shiftキーを押しながら描くと向きが良い感じになります。

03.png

角丸にする

丸くしたい角(アンカーポイント)を選択肢する。
選択したアンカーポイントの内側に丸い点が出てきます。

04.png

丸い点をドラッグさせて好みの丸みにします。

05.png

アクセントをつける

control + A で全選択します。
星を alt + ドラッグ で適当な位置にコピーします。
星を選択し色をつけます。
上の星を #F5D652 色にします。
下の星を #E9C431 色にします。

06.png

星の明るい部分を作る

上の星をいじります。
ドラッグで右下を選択し、deketeキーで削除します。

07.png

削除したことにより、図がぐるりと一周せず、塞がっていないのでペンツールを使い開いているアンカーポイントを2つクリックして塞ぎます。

星の影に当たる部分を作る

下の星をいじります。
今度は逆に右下のみを残します。
前項と逆の範囲を削除し、空いてしまった部分を同じく塞ぎます。

08.png

合体!

選択ツールで下の星(だったもの)を選択します。
交点をあわせ移動させます。(スクリーンショットのショートカットの都合で交点が表示出来ませんでしたので、イメージです。)

09.png

今回は簡単な図形なのでこの方法で合体できますが、複雑なものはこの方法ではできません。
別の図形をやりたい場合はIllustratorの勉強をしましょう。

サイズを調節する

control + A で全選択します。
メニューバーの ウインドウ > 変形 を開きます。
今回はアイコンフォントのような形で使いたいので、高さを調節します。
H:を16pxにします。

10.png

チェーンのアイコンが選択されているのを確認してEnterキーを押します。
フォントサイズが15pxならば星の高さを15pxにします。
キャンバスサイズが大きい方ほど星が小さくなります。

11.png

SVGなので小さくしても大きくしても、画像が荒れることは無いのですが、HTML的にめんどくさいことになりますので、なるべくサイズはこの段階で合わせておきたいです。

余白を消す

control + A で全選択します。
オブジェクト > アートボード > オブジェクト全体に合わせる。
実物を確認したい方は control + [+] でズームしてください。

12.png

ズームすると画像が荒れますが、Illustratorプレビューの都合で荒れているだけでデータ上は荒れていませんのでご安心を。

保存 

control + S で別名保存ウインドウを出します。
ファイル形式をsvgにします。

13.png

保存を押すとSVGオプションが出てきます。

14.png

基本オプションボタンが選択されていない場合は選択肢、文字コードをUTF-8にします。
その他オプションは適当でいいです。しっかり作りたい方はオプションについて調べてください。
以下2つの方法の他に、何かあった場合の編集用にai形式でも保存して残しておいてください。

コードだけ見たい場合

必要なのはコードだけなので保存すると「名称未定.svg」というゴミが出ます。
なので「SVGコード」をクリックします。するとテキストエディターにコードが表示されます。これがSVGの正体です。
何処かにコピペでもして控えておいてください。

保存する場合

適当な場所に適当な名前で保存してください。
それをエディタで開くとxml形式のコードが出てきます。
「コードだけ見たい場合」で表示されるものと同じです。

Illustratorは以上

説明が長くなりましたが、ほとんど操作してないはずです。
IllustratorはPhotoshopより操作が簡単で、SVGが使えることによりWebと親和性が高いのでリッチなアイコンが作りたい方など是非操作を覚えてみてください。
めんどくさい方、Illustratorを持っていない人向けに今回作成したSVGのコードを記載しておきます。

名称未定.svg
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 21.1.0, 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 16.7 16" style="enable-background:new 0 0 16.7 16;" xml:space="preserve">
<style type="text/css">
    .st0{fill:#F5D652;}
    .st1{fill:#E9C431;}
</style>
<path class="st0" d="M13.2,10.3l3.1-3c0.7-0.7,0.3-1.9-0.7-2.1l-4.3-0.6L9.4,0.7C9-0.2,7.7-0.2,7.3,0.7L5.3,4.6L1,5.2
    C0,5.3-0.4,6.6,0.4,7.3l3.1,3l-0.7,4.3c-0.2,1,0.9,1.8,1.8,1.3l3.8-2L13.2,10.3z"/>
<path class="st1" d="M8.3,13.8l3.8,2c0.9,0.5,1.9-0.3,1.8-1.3l-0.7-4.3L8.3,13.8z"/>
</svg>

HTML

簡単なドキュメントファイルを用意します。

index.html
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>星アイコン</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>

</body>
</html>

bodyタグ内にコードを書いて行きます。
その前に、先程作ったSVGをコピペしたいのでSVGファイルを整形します。

SVGファイルの整形

Illustratorで作ったものを整形します。
コードだけ見たい場合でコードを開いている方はそのまま、保存した方はエディタに放り込んでファイルを開いてください。

余計なものを消す

Illustratorで吐き出されたsvgには余分な物がたくさん付いています。
これを削ります。

修正前
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 21.1.0, 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 16.7 16" style="enable-background:new 0 0 16.7 16;" xml:space="preserve">
<style type="text/css">
    .st0{fill:#F5D652;}
    .st1{fill:#E9C431;}
</style>
<path class="st0" d="M13.2,10.3l3.1-3c0.7-0.7,0.3-1.9-0.7-2.1l-4.3-0.6L9.4,0.7C9-0.2,7.7-0.2,7.3,0.7L5.3,4.6L1,5.2
    C0,5.3-0.4,6.6,0.4,7.3l3.1,3l-0.7,4.3c-0.2,1,0.9,1.8,1.8,1.3l3.8-2L13.2,10.3z"/>
<path class="st1" d="M8.3,13.8l3.8,2c0.9,0.5,1.9-0.3,1.8-1.3l-0.7-4.3L8.3,13.8z"/>
</svg>
修正後
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16.7 16">
  <path class="st0" d="M13.2,10.3l3.1-3c0.7-0.7,0.3-1.9-0.7-2.1l-4.3-0.6L9.4,0.7C9-0.2,7.7-0.2,7.3,0.7L5.3,4.6L1,5.2
  C0,5.3-0.4,6.6,0.4,7.3l3.1,3l-0.7,4.3c-0.2,1,0.9,1.8,1.8,1.3l3.8-2L13.2,10.3z"/>
  <path class="st1" d="M8.3,13.8l3.8,2c0.9,0.5,1.9-0.3,1.8-1.3l-0.7-4.3L8.3,13.8z"/>
</svg>

必要なものはsvgタグとその中身になります。
svgタグはsvgであることを宣言するxmlnsviewBoxが必要なのでこの2つだけ残します。
viewBoxは意外と重要で、付け忘れるとCSSの段階でドハマリします。
中身のstyleはCSSに書くので必要ありあせん。

SVGをhtmlに貼り付け

修正したSVGをindex.htmlbody直下に貼り付けてください。
直下に貼り付ける意味ですが、SVGを再利用するので、再利用される前に読み込ませたいという理由からです。なので厳密にbody直下である必要はありません。

index.html
<!-- 省略 -->
<body>
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16.7 16">
    <path class="st0" d="M13.2,10.3l3.1-3c0.7-0.7,0.3-1.9-0.7-2.1l-4.3-0.6L9.4,0.7C9-0.2,7.7-0.2,7.3,0.7L5.3,4.6L1,5.2
    C0,5.3-0.4,6.6,0.4,7.3l3.1,3l-0.7,4.3c-0.2,1,0.9,1.8,1.8,1.3l3.8-2L13.2,10.3z"/>
    <path class="st1" d="M8.3,13.8l3.8,2c0.9,0.5,1.9-0.3,1.8-1.3l-0.7-4.3L8.3,13.8z"/>
  </svg>
</body>
<!-- 見にくいので以降サンプルではbodyタグも省略 -->

この段階でブラウザで表示が確認できます。
ブラウザ幅いっぱいの黒い星が出ていればOKです。

symbol化

星をsymbolタグで囲みます。
(symbolではなくsvgで囲む人も居ます。厳密には挙動は異なりますが、だいたい同じです。)
その後svgタグのviewBoxをsymbolタグへ移動させてください。

index.html
<svg xmlns="http://www.w3.org/2000/svg">
  <symbol viewBox="0 0 16.7 16">
    <path class="st0" d="M13.2,10.3l3.1-3c0.7-0.7,0.3-1.9-0.7-2.1l-4.3-0.6L9.4,0.7C9-0.2,7.7-0.2,7.3,0.7L5.3,4.6L1,5.2
    C0,5.3-0.4,6.6,0.4,7.3l3.1,3l-0.7,4.3c-0.2,1,0.9,1.8,1.8,1.3l3.8-2L13.2,10.3z"/>
    <path class="st1" d="M8.3,13.8l3.8,2c0.9,0.5,1.9-0.3,1.8-1.3l-0.7-4.3L8.3,13.8z"/>
  </symbol>
</svg>

表示の確認をすると星が消えますが正常です。
今回「星」のみなので本来必要ないですが「ハート」や「ひし形」など種類が増えたときsymbolタグが効果を発揮します。
symbolタグは「useで再利用」で使い方がわかります。

サンプル
<svg xmlns="http://www.w3.org/2000/svg">
  <symbol viewBox="0 0 16.7 16">
    <path class="st0" d="M13.2,10.3l3.1-3c0.7-0.7,0.3-1.9-0.7-2.1l-4.3-0.6L9.4,0.7C9-0.2,7.7-0.2,7.3,0.7L5.3,4.6L1,5.2
    C0,5.3-0.4,6.6,0.4,7.3l3.1,3l-0.7,4.3c-0.2,1,0.9,1.8,1.8,1.3l3.8-2L13.2,10.3z"/>
    <path class="st1" d="M8.3,13.8l3.8,2c0.9,0.5,1.9-0.3,1.8-1.3l-0.7-4.3L8.3,13.8z"/>
  </symbol>
  <symbol viewBox="0 0 x y">
    ...ハートのパス
  </symbol>
  <symbol viewBox="0 0 x y">
    ...ひし形のパス
  </symbol>
</svg>

CSS用にidとclass付け

後に再利用されるため
呼び出される側:svg
呼び出す側:icon
ベースで命名します。(適当に命名すると保守で苦労します)

index.html
<svg xmlns="http://www.w3.org/2000/svg" class="svg">
  <symbol viewBox="0 0 16.7 16" id="svg-star">
    <path class="svg-star-0" d="M13.2,10.3l3.1-3c0.7-0.7,0.3-1.9-0.7-2.1l-4.3-0.6L9.4,0.7C9-0.2,7.7-0.2,7.3,0.7L5.3,4.6L1,5.2
    C0,5.3-0.4,6.6,0.4,7.3l3.1,3l-0.7,4.3c-0.2,1,0.9,1.8,1.8,1.3l3.8-2L13.2,10.3z"/>
    <path class="svg-star-1" d="M8.3,13.8l3.8,2c0.9,0.5,1.9-0.3,1.8-1.3l-0.7-4.3L8.3,13.8z"/>
  </symbol>
</svg>

<svg>class
<symbol>id
<path>にそれぞれclass
を与えました。あとで呼び出すのでsymbolには必ずclassではなくidを与えてください。
classがあるのがダメではなくidが無いのがダメです。classidの併用は可能です。)

これでsvgタグの整理は終了です。

useで再利用

新たにsvgタグを書き、中にuseを入れます。
xlink:hrefで呼び出し先を指定します。これが先程symbolにidを指定した理由です。

index.html
<svg xmlns="http://www.w3.org/2000/svg" class="svg">
  <!-- 省略 -->
</svg>

<svg class="icon-ster-true"><use xlink:href="#svg-star"></svg>
<svg class="icon-ster-true"><use xlink:href="#svg-star"></svg>
<svg class="icon-ster-true"><use xlink:href="#svg-star"></svg>
<svg class="icon-ster-false"><use xlink:href="#svg-star"></svg>
<svg class="icon-ster-false"><use xlink:href="#svg-star"></svg>

Firefox:感覚的にuse=symbolになったと思ってください。
webkit系:感覚的にuseの中にオブジェクトがあると思ってください。
MS系:未確認
CSSスプライトのように縦とか横に並んでいるのを想像されている方は基本的には間違いです。データをそのまま出力すると重なっていることが多いです。

classはsvgタグでもuseタグでもどちらでもいいですが今回はsvgタグにつけます。
ブラウザをリロードすると星が5つ並びます。最初に空白が出来ますが呼び出し元が表示されていないため余白が生まれます。

CSSの適用

style.css
.svg {
  display: none; /* 余白を消す */
}

.icon-ster-true,
.icon-ster-false {
  width: 16.7px;
  height: 16px;
}
.icon-ster-true {
  fill: #f5d652; /* webkit */
}
.icon-ster-true .svg-star-0 {
  fill: #f5d652;
}
.icon-ster-true .svg-star-1 {
  fill: #e9c431;
}

.icon-ster-false {
  fill: #cfd6e9; /* webkit */
}
.icon-ster-false .svg-star-0,
.icon-ster-false .svg-star-1 {
  fill: #cfd6e9;
}

記事を書いている途中でバグに気づいたため、Firefoxとwebkitで結果が異なっています。(Firefoxだけちょっとリッチなアイコン(Illustratorと同じ))
星と星の間に隙間がある人とない人が居ると思います。
リストを横並びにした際にできる謎の隙間と原理は同じです。隙間が空いている方はインデントを落とし改行を消せば隙間が埋まります。
width, heightについては'viewBox'のサイズを参照してください。

完成コード

全体像は以下のようになったかと思います。

index.html
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>星アイコン</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
  <svg xmlns="http://www.w3.org/2000/svg" class="svg">
    <symbol viewBox="0 0 16.7 16" id="svg-star">
      <path class="svg-star-0" d="M13.2,10.3l3.1-3c0.7-0.7,0.3-1.9-0.7-2.1l-4.3-0.6L9.4,0.7C9-0.2,7.7-0.2,7.3,0.7L5.3,4.6L1,5.2
      C0,5.3-0.4,6.6,0.4,7.3l3.1,3l-0.7,4.3c-0.2,1,0.9,1.8,1.8,1.3l3.8-2L13.2,10.3z"/>
      <path class="svg-star-1" d="M8.3,13.8l3.8,2c0.9,0.5,1.9-0.3,1.8-1.3l-0.7-4.3L8.3,13.8z"/>
    </symbol>
  </svg>

  <svg class="icon-ster-true"><use xlink:href="#svg-star"></svg>
  <svg class="icon-ster-true"><use xlink:href="#svg-star"></svg>
  <svg class="icon-ster-true"><use xlink:href="#svg-star"></svg>
  <svg class="icon-ster-false"><use xlink:href="#svg-star"></svg>
  <svg class="icon-ster-false"><use xlink:href="#svg-star"></svg>
</body>
</html>
style.css
.svg {
  display: none; /* 余白を消す */
}

.icon-ster-true,
.icon-ster-false {
  width: 16.7px;
  height: 16px;
}
.icon-ster-true {
  fill: #f5d652; /* webkit */
}
.icon-ster-true .svg-star-0 {
  fill: #f5d652;
}
.icon-ster-true .svg-star-1 {
  fill: #e9c431;
}

.icon-ster-false {
  fill: #cfd6e9; /* webkit */
}
.icon-ster-false .svg-star-0,
.icon-ster-false .svg-star-1 {
  fill: #cfd6e9;
}

バグについて

今回遭遇したものに関して言います。
<use>は本来、呼び出し先と同じツリー構造のように振る舞う。とW3Cに書いてあるのですが、webkit系ではそのような振る舞いをしないために起こりました。
以下の記事でも同様の情報がありました。
Design Report(10/18追記:この挙動はブラウザ間によって差異がある)

useで呼び出さず直接、元のsvgをペタペタ貼っていけばこの問題は起こりません。この場合はidは重複するので使わないでください。

サンプル
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>星アイコン</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
  <svg xmlns="http://www.w3.org/2000/svg" class="svg">
    <symbol viewBox="0 0 16.7 16" class="svg-star">
      <path class="svg-star-0" d="M13.2,10.3l3.1-3c0.7-0.7,0.3-1.9-0.7-2.1l-4.3-0.6L9.4,0.7C9-0.2,7.7-0.2,7.3,0.7L5.3,4.6L1,5.2
      C0,5.3-0.4,6.6,0.4,7.3l3.1,3l-0.7,4.3c-0.2,1,0.9,1.8,1.8,1.3l3.8-2L13.2,10.3z"/>
      <path class="svg-star-1" d="M8.3,13.8l3.8,2c0.9,0.5,1.9-0.3,1.8-1.3l-0.7-4.3L8.3,13.8z"/>
    </symbol>
  </svg>

  <svg xmlns="http://www.w3.org/2000/svg" class="svg">
    <symbol viewBox="0 0 16.7 16" class="svg-star">
      <path class="svg-star-0" d="M13.2,10.3l3.1-3c0.7-0.7,0.3-1.9-0.7-2.1l-4.3-0.6L9.4,0.7C9-0.2,7.7-0.2,7.3,0.7L5.3,4.6L1,5.2
      C0,5.3-0.4,6.6,0.4,7.3l3.1,3l-0.7,4.3c-0.2,1,0.9,1.8,1.8,1.3l3.8-2L13.2,10.3z"/>
      <path class="svg-star-1" d="M8.3,13.8l3.8,2c0.9,0.5,1.9-0.3,1.8-1.3l-0.7-4.3L8.3,13.8z"/>
    </symbol>
  </svg>

  <!-- 繰り返しにつき省略 -->
</body>
</html>

最後に

最後まで読んだ方、お疲れ様でした。
実際に作ると大したこと無いのですが、記事にするとこんなになってしまいました。
このタグに限っては個人的にMDNの解説も微妙だったので勉強したい方はW3Cを読むことをオススメします。