SVGでやることのまとめ。
使いまわせるSVG
ロゴとかアイコンとかシンボルとか、Webサイトの中のいろいろなところで使われていて、それでいて色違いも必要だったりする小っこい画像たち。みるみる増えてしまってもう仕方ないですね…X(。そんな小っこい画像をひとまとめに管理できる、SVGスプライトについてまとめます。
アイコン一式SVG
バラバラのアイコンたちをひとまとめにして、取っ散らかった画像フォルダをスッキリ片付けちゃいましょう;D!
ということで、例えば、ボタンの矢印とかアイコンとか、ロゴとかシンボルとか、Webサイトの至るところに蔓延る小っこいアイコンを、ひとつのSVGファイルに詰め込んで使いたいやつだけ表示させるやつのつくり方をまとめます。
仕組み
「SVGでやることのまとめ。」という記事で紹介したuse要素を使います。
ひとつのSVGファイルに、アイコンぜんぶを詰め込んで、それぞれにid属性を割り振れば、use要素でお目当のアイコンが呼び出せるって寸法ですねー:D!
<svg width="20" height="20" viewBox="0 0 20 20"><use href="ico.svg#id"></use></svg>

ここでは、Lopan.jpで使ってるアイコンとロゴを詰め込んだ「LopanのアイコンSVG」を作ります:)。
イラレデータの用意
まずはイラレデータを準備。「新規...(⌘+N)」で、ひとまず、サイズを「Web」として開きます。
まずは、詰め込みたいロゴやアイコンのオブジェクトを、このaiデータに集めます。と言っても、アイコンはすでに有り物なので、コピペしてくるだけです:D。
アイコン集め
Lopan.jpで使っているアイコン(以下、Lopanのアイコン)をひとつ残らずコピペ。
Lopanのアイコンは、塗りは使わず線だけで描くようにしています。アートボード(後のviewBox)のサイズは20px×20pxに揃えて、線の太さも1pxか2pxに統一しています。

SNSアイコン集め
SNSアイコンはそれぞれ、公式サイトから、ガイドラインを参照しつつダウンロードしたものをコピペして、サイズを揃えて並べておきます。サイズは40px×40pxに揃えてます。

元の見た目が、丸かったり四角かったりバラバラなので、どっちかに統一したいところですね…¦‹。
ここは「ブランドカラーの丸の中に白抜き」という見た目に揃えることにします。もともと丸くなかったアイコンだけ、40px×40pxの円を敷いて、その中にアイコンがバランスよく入るように、大きさを調整します。

他の丸くないアイコンも同じように体裁を整えて、いっちょあがり!

SNSアイコンについて、詳しくは公式サイトを参照のこと。
Instagramのブランドカラーは下記サイトを参考にしてます。
ロゴやイラスト集め
サイトのロゴとイラストもコピペ。サイズは特に気にせず、使うサイズのままです。

これにて詰め込みたいロゴやアイコンぜんぶ出揃いました;D!
一旦、「lopan_icon.ai」として保存しておきます。
イラレデータを整える
集めたアイコンたちを、SVGで書き出す用に、アートボードに配置したり、レイヤーに名前をつけたりします。
レイヤーを整える
その前にまず、コピペしっぱなしでハチャメチャしていたレイヤーを、整理整頓です:D。
SNSアイコンはぜんぶ、背景に敷いている丸とロゴをグループ化した後、ひとつのレイヤーのサブレイヤーとしてまとめちゃいます。

ここでは「Layer 1」というレイヤーの中に移動することにします(下図)。
オブジェクトを移動して空っぽになったレイヤーは削除しちゃえば、だいぶスッキリしますねー:D!

あと、SNSアイコンのオブジェクトの構造も、揃えておきます。
ここでは、GitHubやCodePenのロゴの作りに合わせることにします。ブランドカラーの上に白地のロゴが乗っているのではなくて、ブランドカラーの丸をロゴの形でくり抜いた状態にしておくんです。
背景のオブジェクトを前面のオブジェクトでくり抜くには、丸とアイコンを選択して「パスファインダー」パネルの「前面オブジェクトで型抜き」を適用します。LINEアイコンみたく、背景の丸とフキダシと文字が3段で重なってる場合は、「中マド」というのが使えます;)。


Lopanのアイコンは、ひとつずつ、アイコンを作るときに目安にしたガイドラインとグループ化しておきます。下図の「<長方形>」というサブレイヤーがガイドラインのこと。 ※ガイドがロックされている場合はガイドのロックを解除(⌘+option+;)しないと触れないので注意です。


最後にレイヤー名を「sns」と「ico」に変えて、レイヤー整理整頓、完了!
レイヤーに名前をつける
SVGに書き出した際、レイヤーに付けた名前が、その要素のid属性として反映されるのでした。詳しくは「SVGでやることのまとめ。」という記事を参照のこと。つまり、use要素で呼び出す際に指定するid名になるということなので、レイヤーには、そのアイコンだとすぐ分かる名前を付けると、分かり良いですね。
それから、SVGに書き出された際、アイコンはそれぞれ、g要素で括られた状態であって欲しいので、レイヤー名が「<グループ>」となっていないレイヤーは、グループ化(⌘+G)して、グループレイヤーの中に入れてから、そのグループレイヤーの名前を書き換えるようにします。
ここでは、Twitterアイコンには「twitter」、Facebookアイコンには「facebook」という要領で、下図のように名付けました。

アートボードに振り分ける
すべてのアイコンに名前を付けたら、SVGで書き出す用のアートボードに割り振ってゆきます。
まずは、Lopanのアイコン用に、20px×20pxのアートボードを用意します。適当な位置にアートボードを作ってから、アートボードツールをダブルクリックして、サイズを整えます。元からあった「アートボード 1」は削除して、「アートボード 2」の名前を「ico」に変更します。

Lopanのアイコンをぜんぶ選択したらば、「整列」パネルの整列方法が「アートボードに整列」になっていることを確認して、おもむろに「水平方向中央に整列」と「垂直方向中央に整列」をクリック。Lopanのアイコンがすべて「ico」アートボードに重なって配置されました:D!

同じ要領で、SNSアイコンには、40px×40pxのアートボードを用意して、名前を「sns」に変えたら、SNSアイコンをぜんぶ「sns」アートボードに集結させます。
SNSアイコンの色は、SVGにするときにはデフォルト色(#000)にしておいて、後からCSSで色を指定するようにしたいので、塗り色をぜんぶ黒くしておきます。

ロゴとイラストはそれぞれ、アートボードツールでクリックして、ぴったしサイズのアートボードを作ってから、アートボードのサイズを整数に調整。アートボードの名前は、サブレイヤーの名前と同じにしておきます。

これにて、イラレのデータ準備完了!

SVGに書き出す
イラレデータが整ったら、いよいよ書き出します!
「別名で保存...(⌘+shift+S)」でも良いですけれど、今回は、「スクリーン用に書き出し...(⌘+option+E)」から、SVGファイルを書き出すことにします。
スクリーン用に書き出し
すると、「スクリーン用に書き出し」パネル(下図)が現れます。
スクリーン用に書き出しでは、書き出す対象と、書き出し先のフォルダー、書き出すファイルのフォーマットを選択することができます。JPG/PNG/SVG/PDFにいっぺんに書き出せるほか、画像の拡大率や、サフィックス(接尾辞)に使われる文字列を指定できたりなど、レスポンシブ時代に適した書き出し方法になってます:)!

アートボードごとに書き出す方法と、アセットに登録したオブジェクトを書き出す方法がありますが、ここでは「アートボード」を選択。アートボード枠の中に、先ほど用意したアートボードがズラッと並んでいます。
「選択」の項目で、書き出したいアートボードの範囲を選択します。もしくは、左枠のサムネイルにチェックでも選ぶことができます。今回はぜんぶ書き出したいので、「すべて」をチェック。
「裁ち落としを含める※1」は、チェックしてもしなくてもどちらでも良いです。「書き出し先」に、SVGファイルを書き出す場所を指定します。
「書き出し後に場所を開く」は、すでに書き出す場所は開いてあるので、チェックしなくて大丈夫。
「サブフォルダーを作成」も、今回はフォーマットがSVGのみなので※2、チェックを外しておきます。
- ※1 「裁ち落とし」とは、印刷物のデータにある、アートボードの周りを囲う赤枠(塗り足し領域)のこと。「裁ち落としを含める」とは、塗り足し部分も含めて書き出すということになります。新規作成時に、プロファイルで「Web」を選んでいる場合には、裁ち落としサイズが「0px」になっているので、気にしなくて大丈夫:)。
裁ち落としのサイズは、メニュー「ファイル」の「ドキュメント設定...」の「全般」の項目で設定できます。 - ※2 いろんなフォーマット(PNGとかJPGとか)で書き出す場合には、ここにチェックしておくと、フォーマット毎にフォルダーが作られて、その中に画像が書き出されるようになります。

フォーマットの右上のアイコンをクリックすると、「形式の設定」パネルが現れます。ここで、フォーマットごとに、書き出す際のオプションが設定できます。
SVGにおいては、別名で保存の時の「詳細オプション」にあたる項目とだいたい一緒かな:‹。ここでは、上図のような感じで設定しました。
「スタイル」には「内部 CSS」を選択。今回はテキストも画像も使ってないので「フォント」と「画像」はデフォルトのままで大丈夫で、「オブジェクト ID」は「レイヤー名」にしておきます。「小数点以下の桁数」は「3」にして、「縮小」という項目にチェックしておきます。※詳しくは後述。「フォーマット」の「形式」は、もちろん「SVG」を選択。したら「アートボードを書き出し」をクリックです;)!

SVGファイルがいっぺんに書き出されましたーXD!
アートボード名がそのままファイル名となって書き出されます。

「Lopanのアイコン」は、せっかく単純な作りにしてるので、小数点以下の桁数は「1」にして、「ico.svg」だけもう一度書き出し直すことにします。で、書き出し完了ー;D!

SVGコード
書き出されたソースコードはこんな感じ。以下は「ico.svg」になります。
なんと、すでに圧縮された状態で書き出されるのです…!XD
見やすく改行とインデントを入れると、以下のようになります。g要素に、アイコンごとのid属性が振られてるのがわかりますね!
ここから、Webサイトで使う時に扱いやすいように、もうちょっとだけカスタマイズしてゆきます。;)
書き出し形式の詳細設定
「形式の設定」パネルの設定項目は、別名で保存の時の「詳細オプション」とほとんど同じですけれど、項目が整理されて、よりわかりやすくなってます。それからなんたって、「縮小」にチェックすることで、SVGを最小限に圧縮できるのが、大助かり:D!
「スタイル」

- 内部CSS
- SVGファイル内のstyle要素にスタイルを定義して、class属性でもって、スタイルが適用されます。(別名で保存の時には「スタイル要素」という項目だったところ。)
- インラインスタイル
- 要素ごとに、直接style属性を指定して、スタイルが適用されます。(別名で保存の時には「スタイル属性」という項目だったところ。)
- プレゼンテーション属性
- SVG要素に用意されている、見た目を変えるための属性によって、スタイルが適用されます。別名で保存の時と同じ。
「フォント」と「画像」

- アウトラインに変換
- テキストすべてアウトラインが取られ、オブジェクトとして書き出されます。
- SVG
- テキストはtext要素で括られて、ちゃんと文字として書き出されます。文字の詰めが調整されているテキストは、一文字ずつtspan要素で括られ、x/y属性を駆使してカーニングを再現します。
- 保持
- リンクで配置された画像はリンクで、埋め込まれた画像は「base64」にエンコードされた状態で書き出されます。イラレで配置している状態を保持する、ということ;)。
- 埋め込み
- イラレ内に配置された画像はすべて埋め込まれ、base64にエンコードされた状態で書き出されます。
- リンク
- イラレ内に配置された画像は、埋め込んだ画像もすべて、リンクされた状態で書き出されます。元画像が同じフォルダ内にない場合は、埋め込まれた画像も画像ファイルとして一緒に書き出します。
base64については以下の記事が詳しいです。
base64ってなんぞ??理解のために実装してみた - Qiita
「オブジェクト ID」

- レイヤー名
- 別名で保存の時と同じように、レイヤー名がid属性の値として使われます。オブジェクトのスタイルを指定するためのclass名は、
cls-1
という風に指定されます。(別名で保存の時にはst1
という風だったところ。) - 最小
- id属性は出力されず、オブジェクトのスタイルを指定するためのclass名には、
a
とかb
とかごく短い文字が指定されます。 - 固有
- id属性に、完全ユニークな(めちゃんこ長い)名前が指定され、レイヤー名はdata-name属性の値として使われます。
「小数点以下の桁数」
別名で保存の時と同じ、パスやアンカーポイントの位置の、小数点以下の最大桁数(1桁〜5桁まで)を指定します。桁数が多いほど、描画の精度が上がります。「3」が最適とされています。
ここでは、単純なつくりの「Lopanのアイコン」だけは「1」にして、その他は「3」にして書き出しています。
「縮小」と「レスポンシブ」

「縮小」にチェックすると、書き出されるSVGファイルから、余計な記述が削減され圧縮された状態で書き出されます。つまり、別名で保存の時に、書き出した後でやってた、ソースコードを圧縮する工程が端折れるわけですね:D!すごい、大助かり!
「レスポンシブ」にチェックすると、svg要素にwidth属性とheight属性が出力されなくなりますが、ここでは、width/height属性も書き出すことにしてます。
SVGをカスタマイズ
さぁ、書き出されたSVGファイルを使うとき、より使い勝手が良いように、もうちょっとだけカスタムです。
use要素を使ってSVGファイル内の要素を読み込むとき、style要素は読み込まれないのでした。なのでまずは、SVGファイル内のstyle要素の中で定義されているスタイルを、アイコンごと(g要素ごと)に指定し直す必要があるってことですね…:‹。
「Lopanのアイコン」の場合は、style属性の内容は、下ソースコードのようになってます。
.cls-1,.cls-2,.cls-3,.cls-4{fill:none;stroke:#000;stroke-linecap:round;stroke-linejoin:round;}
.cls-1{stroke-width:2px;}
.cls-3{stroke-width:1.5px;}
.cls-4{stroke-width:3px;}
.cls-1
に指定されているスタイルは、fill:none;stroke:#000;stroke-linecap:round;stroke-linejoin:round;
(以下、最初のそれ)と、stroke-width:2px;
。これを、class="cls-1"
の要素にstyle属性の値として指定し直せばよいわけですねー。
ただし、線の色だけは、HTML側のCSSで変えられるようにしておきたいので、stroke:#000;
だけは外しておくことにします。それからstroke-widthプロパティは、単位がなければpxとして適用してくれるので、px
は端折っちゃいます。
<g id="next"><polyline class="cls-1" points="7 17 15 10 7 3"/></g>
↓
<g id="next"><polyline style="fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:2" points="7 17 15 10 7 3"/></g>
他のclassもじゃんじゃか、style属性で指定し直していきます。
cls-2
というclass名の要素には最初のそれだけ。cls-3
には、最初のそれとstroke-width:1.5
。cls-4
には、最初のそれとstroke-width:3
、という具合。
ものすごく無駄が多いですね…⁑|!…重複しているスタイルをなんとか一箇所にまとめたいです…。
なので、最初のそれは、use要素で呼び出す時にHTML側で指定することにして、SVGファイル内では、stroke-width
だけを指定することにします。うん、だいぶスッキリしました:)。
「SNSアイコン」のスタイルはこれだけでした。
.cls-1{fill-rule:evenodd;}
fill-ruleプロパティは、オブジェクトの塗りのルールを指定します。evenodd
という値にすると、パスが交差するたびに塗り面を交互に切り替えるというルール※なんですけれど、GitHubのアイコンを見ても、どこもパスが交差してないんですよねぇ…。なのでこの指定はなくても大丈夫かもしれません。削除しちゃいます!
※イラレのメニュー「効果」の「パスファインダー」で「中マド」を適用した感じ。
アイコンごとのブランドカラーは、HTML側のCSSで指定することになるので、特にstyle属性を指定することなくこのままでOK;)。
fill-ruleプロパティについて、詳しくは下記ページを参照のこと。
fill-rule - SVG: Scalable Vector Graphics | MDN
「ロゴのパンちゃん」も、Lopanのアイコンと同じように、SVGファイル内では線の太さだけを指定したいところですけれど、cls-3
だけなんだかイレギュラーですね…。
.cls-1,.cls-2,.cls-3{fill:none;stroke:#553968;}
.cls-1,.cls-2{stroke-linecap:round;stroke-linejoin:round;}
.cls-1{stroke-width:1.5px;}
.cls-2{stroke-width:2px;}
.cls-3{stroke-miterlimit:10;stroke-width:2.5px;}
stroke-linecap:round
は、線の端を丸める指定、stroke-linejoin:round
は線が折れた時の角を丸める指定になります。
stroke-miterlimit:10
というのは、線が折れた時の角がツンツンじゃなくなる(角が面取りされる)までの角度を制限するための指定で、10
だと、約11.5°未満の時に面取りされます。
cls-3
はロゴのパンちゃんの目にあたる要素なので、他の要素と一緒に、stroke-linecap:round
とstroke-linejoin:round
を指定しちゃっても大丈夫そう。角が丸くなることで、stroke-miterlimit:10
の指定も必要なくなるから、以下のようにまとめられます。
.cls-1,.cls-2,.cls-3{fill:none;stroke:#553968;stroke-linecap:round;stroke-linejoin:round;}
.cls-1{stroke-width:1.5px;}
.cls-2{stroke-width:2px;}
.cls-3{stroke-width:2.5px;}
これなら、「Lopanのアイコン」と同じように、線の太さだけSVGファイル内で指定して、その他はHTML側のCSSから指定することができますね:D
「Lopanのロゴ」も「パンちゃん」も、「Lopanのアイコン」と同じように、線の太さだけ指定するようにします。
パンちゃんの目は、線がなくて塗りだけにしたいので、目にあたるpath要素だけg要素で括って、stroke-width:0
を指定しています。これだけだと、HTML側のCSSから目の塗り色を指定すると、体までその塗り色が反映されちゃうので、体には別途、塗り色が適用されないようにfill:none
も指定しておきます。
以上でカスタマイズ終了ー!あとは、それぞれのSVGファイルから、全部のアイコンをひとつのSVGファイルにまとめちゃえば完成です。
ここでは、「ico.svg」に、他のSVGファイルのアイコンをコピペすることにします。
「LopanのアイコンSVG」出来上がりXD!
LopanのアイコンSVGの使い方
すべては「ico.svg」の中に入っているので、use要素で下記のようにして、id属性さえ変えれば、すべてのアイコンが呼び出せます。
<svg width="20" height="20" viewBox="0 0 20 20"><use href="ico.svg#download"></use></svg>
ただし、Lopanのアイコン以外は、width/height/viewBox属性の値は20
じゃなく、それぞれ、元のsvg要素のサイズを指定しないといけません。
SNSアイコンの場合は、縦横40pxなので、下記のように指定します。
<svg width="40" height="40" viewBox="0 0 40 40"><use href="ico.svg#twitter"></use></svg>
viewBox属性の値は、表示する範囲を、左上のXY座標(0 0
)と右下のXY座標(40 40
)でもって指定しています。
width/height属性は、SVGファイルのHTML上のサイズを指定していて、viewBox属性では、そのサイズの中にどの範囲を表示させるかを指定しているってことですね:D。
ico.svgの中のアイコンをぜんぶ並べてみました。SNSアイコンはカーソルを乗せた時にブランドカラーになるようにしてます:)。
width/height/viewBox属性のサイズを間違えると下のサンプルのようになってしまうので注意です。
※width/height
が違うと表示サイズが小さくなっていて、viewBox
が違うと表示する範囲が狭くなってるのがわかります。
あとがき
アイコンとかロゴなので、線の太さや形は変えずに、色だけ変えられる、完全Lopan仕様の便利なアイコンセットができました。ホクホク…:)
…と思ってたんですが、最後の最後に、右向きの矢印「」がないことに気付いちゃいました…:|。
けれどもそこは焦らず、イラレで新たに、20px×20pxの右向き矢印を作って、アートボードとレイヤー名を整えたらば、スクリーン用に書き出し...!

<svg id="レイヤー_1" data-name="レイヤー 1" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><defs><style>.cls-1{fill:none;stroke:#000;stroke-linecap:round;stroke-linejoin:round;stroke-width:2px;}</style></defs><title>arrow_next</title><g id="arrow_next"><polyline class="cls-1" points="10 3 18 10 10 17"/><line class="cls-1" x1="18" y1="10" x2="2" y2="10"/></g></svg>
書き出されたSVGファイルのg要素の部分だけ、ico.svgにコピペして、class属性をstyle属性に変えてstroke-width:2
としておけば、追加完了!
左向き矢印(arrow_prev
)と、上向き矢印(arrow_up
)の間に入れました:D。
︙
<g id="arrow_prev"><polyline style="stroke-width:2" points="10 3 2 10 10 17"/><line style="stroke-width:2" x1="2" y1="10" x2="18" y2="10"/></g>
<g id="arrow_next"><polyline style="stroke-width:2" points="10 3 18 10 10 17"/><line style="stroke-width:2" x1="18" y1="10" x2="2" y2="10"/></g>
<g id="arrow_up"><polyline style="stroke-width:2" points="17 10 10 2 3 10"/><line style="stroke-width:2" x1="10" y1="2" x2="10" y2="18"/></g>
︙
最後のLopanのアイコンSVGをダウンロードする(ico_fix.zip)
てなもんで以上、「使いまわせるSVG(の作り方)についてのまとめ」でした;)。
最後まで読んでいただきありがとうございました!
Comment & Pingback