SVGのオブジェクトごとにCSSで色を切り替える
デザインpsdを見ながらhtmlでコーディングするとき、たくさん画像を書き出しますよね。 たとえばpngのアイコンを作る場合、形が同じでも色が違えばpngファイルをたくさん書きださなければいけません。色だけ変えたものをひとつずつ、@2xサイズも用意してちまちまと……書き出して……
やってらんないっすよ!
せめて、形が同じなら使いまわしたい……
そう!SVGを使えば、同じオブジェクトを使ってCSSで色だけ変えたものを量産できるのです!
「それだったらwebフォントでいいじゃん」と思われるかもしれませんが、webフォントはアイコンひとつにつき1色しか使えませんよね?SVGでやればアイコンひとつでも複数色使うことができます。
このSVGアイコンを使いまわして、
こんなかんじでカラフルなアイコンを量産しますよー!
ベクターでアイコンを作成
アイコン作るのがめんどくさい人はicomoonから適当なアイコンを見つくろってDLしましょう。 プロジェクトを新規作成し、フッタの「Selection」からお好みのアイコンをクリックし、「Generate SVG & More」からDLします。
今回はicomoonからDLした場合の手順を説明します。
DLしたアイコンを調整する
今回はこちらの吹き出しがふたつ重なったアイコンを使用します。
まずicomoonからDLした状態のままだと、オブジェクトごとに分かれていない場合があるのでその場合はIllustratorで編集します。
<?xml version="1.0" encoding="utf-8"?> <!-- Generated by IcoMoon.io --> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="34" height="32" viewBox="0 0 34 32"> <path d="M25.132 13.165c0-5.165-5.627-9.352-12.566-9.352s-12.566 4.187-12.566 9.352c0 3.104 2.032 5.854 5.16 7.555-0.009 0.027-2.492 4.545-2.492 4.545s7.582-2.892 7.603-2.904c0.744 0.103 1.511 0.155 2.295 0.155 6.939 0 12.566-4.187 12.566-9.351zM34.385 16.087c0-5.164-5.297-9.314-11.031-9.351 8.22 8.188-1.461 16.912-9.351 16.912 0 0 0.877 1.79 7.816 1.79 0.783 0 1.551-0.054 2.295-0.156 0.021 0.014 7.604 2.904 7.604 2.904s-2.484-4.517-2.492-4.544c3.127-1.701 5.159-4.452 5.159-7.555z"></path> </svg>
path
要素が実際のオブジェクトを表すのですが、こちらはふたつの吹き出しがひとつのオブジェクトになっているので、ふたつのオブジェクトに分けます(もともと分かれていたり、自分で作成する場合は「SVGファイルをエディタで編集」のステップまで飛ばしていただいてOKです)。
ちなみにオブジェクトはpath
要素だけでなく、rect
要素やcircle
要素などさまざまなものがあるので、わからないときはW3Cのドキュメントを見て調べてみてください。
Illustratorで編集
オブジェクトを選択し、「オブジェクト」→「複合パス」→「解除」を選択します。
ちなみにオブジェクトが複合パスかどうかはレイヤーパネルを開き、左の▼アイコンをクリックするとわかります。
ちなみに複合パスを解除した後はこんなかんじになります。ふたつのオブジェクトに分かれていますね!
SVGで保存
「別名で保存」から「ファイル形式:SVG」を選択して保存します。 SVG保存設定はこんなかんじです。
SVGファイルをエディタで編集
保存したSVGをお好きなエディタで開きます。私はSublime Textを使っています。
Illustratorで保存したままの状態だと余計なコードがついてるので削除します。
保存したままの状態↓
<?xml version="1.0" encoding="utf-8"?> <!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <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" width="34px" height="32px" viewBox="0 0 34 32" enable-background="new 0 0 34 32" xml:space="preserve"> <path d="M25.1,13.2c0-5.2-5.6-9.4-12.6-9.4S0,8,0,13.2c0,3.1,2,5.9,5.2,7.6c0,0-2.5,4.5-2.5,4.5s7.6-2.9,7.6-2.9 c0.7,0.1,1.5,0.2,2.3,0.2C19.5,22.5,25.1,18.3,25.1,13.2z"/> <path d="M34.4,16.1c0-5.2-5.3-9.3-11-9.4c8.2,8.2-1.5,16.9-9.4,16.9c0,0,0.9,1.8,7.8,1.8c0.8,0,1.6-0.1,2.3-0.2c0,0,7.6,2.9,7.6,2.9 s-2.5-4.5-2.5-4.5C32.4,21.9,34.4,19.2,34.4,16.1z"/> </svg>
余計なコードを削除した状態↓
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="34px" height="32px" viewBox="0 0 34 32"> <path d="M25.1,13.2c0-5.2-5.6-9.4-12.6-9.4S0,8,0,13.2c0,3.1,2,5.9,5.2,7.6c0,0-2.5,4.5-2.5,4.5s7.6-2.9,7.6-2.9 c0.7,0.1,1.5,0.2,2.3,0.2C19.5,22.5,25.1,18.3,25.1,13.2z"/> <path d="M34.4,16.1c0-5.2-5.3-9.3-11-9.4c8.2,8.2-1.5,16.9-9.4,16.9c0,0,0.9,1.8,7.8,1.8c0.8,0,1.6-0.1,2.3-0.2c0,0,7.6,2.9,7.6,2.9 s-2.5-4.5-2.5-4.5C32.4,21.9,34.4,19.2,34.4,16.1z"/> </svg>
すっきりしましたね。
注意点
ちなみに、このときpath
要素などのオブジェクトにfill
属性がついていると、CSSで色を変えられなくなってしまうので注意してください!色が変わらないことが決まっている場合は大丈夫ですが、今回は色を変えたいので消してしまいましょう。
オブジェクトをg要素で囲む
g
要素とはオブジェクトをグループ化するための要素です。g
要素でオブジェクトを囲んでクラスをつけることで、CSSからg
要素を操作できるようになります。
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="34px" height="32px" viewBox="0 0 34 32"> <symbol id="IconComments"> <g id="#IconComments-back"> <path d="M25.1,13.2c0-5.2-5.6-9.4-12.6-9.4S0,8,0,13.2c0,3.1,2,5.9,5.2,7.6c0,0-2.5,4.5-2.5,4.5s7.6-2.9,7.6-2.9 c0.7,0.1,1.5,0.2,2.3,0.2C19.5,22.5,25.1,18.3,25.1,13.2z"/> </g> <g id="IconComments-front"> <path d="M34.4,16.1c0-5.2-5.3-9.3-11-9.4c8.2,8.2-1.5,16.9-9.4,16.9c0,0,0.9,1.8,7.8,1.8c0.8,0,1.6-0.1,2.3-0.2c0,0,7.6,2.9,7.6,2.9 s-2.5-4.5-2.5-4.5C32.4,21.9,34.4,19.2,34.4,16.1z"/> </g> </symbol> </svg>
まず、path
要素をg
要素で囲みます。↑のコードではそのg
要素2つをさらにsymbol
要素で囲んでいます(symbol
要素で囲むのは、参照するための要素として定義するためです)。今回このSVGコードは別の場所から参照します。
これでSVGファイルの準備が整いました!次から実際にCSSでオブジェクトごとに色を切り替えます。
インラインSVGで記述
SVGはimg
要素やobject
要素で読み込むことができますが、今回解説する方法はインラインSVGで記述する必要があります。
なのでhtmlに直接SVGコードを書きます。
<!DOCTYPE html> <html> <head> <meta charset='utf-8'> <meta content='width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no' name='viewport'> <title>SVGテスト</title> <link href="/stylesheets/application.css" rel="stylesheet" /> </head> <body> <!-- htmlに直接svgを書く --> <svg class='SvgIcon' viewbox='0 0 205.2 145.4' xmlns:xlink='http://www.w3.org/1999/xlink' xmlns='http://www.w3.org/2000/svg'> <symbol id='IconComments'> <title>comments</title> <g id='IconComments-back'> <path d='M150,55.8C150,25,116.4,0,75,0C33.6,0,0,25,0,55.8c0,18.5,12.1,34.9,30.8,45.1c-0.1,0.2-14.9,27.1-14.9,27.1
 s45.2-17.3,45.4-17.3c4.4,0.6,9,0.9,13.7,0.9C116.4,111.6,150,86.6,150,55.8L150,55.8z'></path> </g> <g id='IconComments-front'> <path d='M205.2,73.2c0-30.8-31.6-55.6-65.8-55.8c49.1,48.9-8.7,100.9-55.8,100.9c0,0,5.2,10.7,46.6,10.7c4.7,0,9.3-0.3,13.7-0.9
 c0.1,0.1,45.4,17.3,45.4,17.3s-14.8-27-14.9-27.1C193.1,108.2,205.2,91.8,205.2,73.2L205.2,73.2z'></path> </g> </symbol> </svg> </body> </html>
.SvgIcon { position: absolute; width: 0; height: 0; }
上記のSVGは直接描画したくないので、CSSで非表示にしておきます。ちなみに非表示にするのにdisplay: none;
を使用するとグラデーションなどは打ち消されてしまうため、それ以外の方法で非表示にしたほうがベターです。
そして定義したSVGを使い回すため、新たなsvg
要素の中にuse
要素を追加します。
<!DOCTYPE html> <html> <head> <meta charset='utf-8'> <meta content='width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no' name='viewport'> <title>SVGテスト</title> <link href="/stylesheets/application.css" rel="stylesheet" /> </head> <body class='index'> <svg class='SvgIcon' viewbox='0 0 205.2 145.4' xmlns:xlink='http://www.w3.org/1999/xlink' xmlns='http://www.w3.org/2000/svg'> <symbol id='IconComments'> <title>comments</title> <g id='IconComments-back'> <path d='M150,55.8C150,25,116.4,0,75,0C33.6,0,0,25,0,55.8c0,18.5,12.1,34.9,30.8,45.1c-0.1,0.2-14.9,27.1-14.9,27.1
 s45.2-17.3,45.4-17.3c4.4,0.6,9,0.9,13.7,0.9C116.4,111.6,150,86.6,150,55.8L150,55.8z'></path> </g> <g id='IconComments-front'> <path d='M205.2,73.2c0-30.8-31.6-55.6-65.8-55.8c49.1,48.9-8.7,100.9-55.8,100.9c0,0,5.2,10.7,46.6,10.7c4.7,0,9.3-0.3,13.7-0.9
 c0.1,0.1,45.4,17.3,45.4,17.3s-14.8-27-14.9-27.1C193.1,108.2,205.2,91.8,205.2,73.2L205.2,73.2z'></path> </g> </symbol> </svg> <!-- svg要素の中にuse要素 --> <svg class='Svg01'> <!-- use要素のxlink属性で先ほど定義したg要素を参照。use要素にクラスを指定しておきます --> <use class='Svg01-front' xlink:href='#IconComments-front'></use> <use class='Svg01-back' xlink:href='#IconComments-back'></use> </svg> </body> </html>
ブラウザで開くとこんなかんじで表示されていると思いますー。 ここから楽しい楽しいスタイリングですよ👐
CSSでスタイリング
use
要素にクラスをつけたので、普通にクラスを指定してCSSを装飾していきます。
SVGの場合はfill
属性に色を指定します。
.Svg01-front { fill: #42AFE3; } .Svg01-back { fill: #97CD76; }
じゃーん! カラフルになりましたね。
同じように量産していけば……
<svg class='Svg01'> <use class='Svg01-front' xlink:href='#IconComments-front'></use> <use class='Svg01-back' xlink:href='#IconComments-back'></use> </svg> <svg class='Svg02'> <use class='Svg02-front' xlink:href='#IconComments-front'></use> <use class='Svg02-back' xlink:href='#IconComments-back'></use> </svg> <svg class='Svg03'> <use class='Svg03-front' xlink:href='#IconComments-front'></use> <use class='Svg03-back' xlink:href='#IconComments-back'></use> </svg>
.Svg01-front { fill: #42AFE3; } .Svg01-back { fill: #97CD76; } .Svg02-front { fill: #97CD76; } .Svg02-back { fill: #FCE473; } .Svg03-front { fill: #ED6C63; } .Svg03-back { fill: #42AFE3; }
じゃじゃじゃーん! いろんなカラーバリエーションのアイコンができました。
しかもSVGなので、Retineディスプレイでも綺麗です!@2xや@3xで書き出す必要もありませんやったね!
たとえば、デザインテーマごとにアイコンの形は一緒だけど色だけ変わる、みたいなときに大変便利です。 試してみてください〜