Gulpを使ったSVGスプライトのアイコンシステムとワークフローの作り方

Advertisement

SVGスプライトって、なんか複雑なイメージがありませんか?
僕はそうでした。なんか、面倒くさそう。。。どこから始めて良いかわからない。。。といった感じでずっと手をつけられずにいました。

でも、今回やってみて思ったんですが、一度ワークフローを確立してしまえばアイコン管理がかなり便利になります。CSSスプライトの時よりも管理が楽になりますし、表示サイズや今後の高解像度対応を気にしなくて良くなるのも嬉しいですね。

SVGスプライトについての英語のリソースはあるのですが、説明が多く、とっつきにくいものも多い印象なので、ここではできるだけシンプルに必要なことだけをまとめてみたいと思います。

では、SVGスプライト・アイコンシステムのGulpを使ったワークフローの構築、始めましょう!

目次

  1. 達成したいこと
  2. デモページ
  3. SVGスプライトの仕組み
  4. ブラウザサポート
  5. 用意するもの
  6. 導入ステップ
  7. 最後に

達成したいこと

  • CSSスプライト と同等のことをSVGで実現する
  • 表示速度改善のためにSVGアイコンを1つの外部ファイルで読み込む
  • SVGスプライト画像作成の自動化
  • フォールバック用PNG画像作成の自動化
  • SVGアイコンのCSSでの色指定

デモページ

このワークフローで作ったSVGアイコンを使ったデモページはこちら から。

SVGスプライトの仕組み

SVGスプライトのアイコンシステムの構築にはいくつか方法がある ようですが、ここでは個人的に一番シンプルで簡単だと思った方法をご紹介します。symbolタグを使って複数アイコンを1つのSVGファイルに記述し、svguseタグから参照する方法です。

<symbol>で複数アイコンを1つのSVGファイルに記述

まずは、以下のように複数のアイコンが入ったSVGファイルを作ります。ポイントは<symbol>要素にidviewBoxが指定されているところです。

iduseでアイコンを参照する際に使います。viewBoxでは、それぞれのアイコンのサイズを指定します。アイコンのサイズは全て同じである必要はありません。

<svg xmlns="http://www.w3.org/2000/svg" class="hide">
  <symbol id="hogehoge" viewBox="0 0 32 32">
    <!-- 1つのアイコンのpathやshapeなどのSVG要素 -->
  </symbol>
  <symbol id="gehogeho" viewBox="0 0 32 32">
    <!-- 1つのアイコンのpathやshapeなどのSVG要素 -->
  </symbol>
</svg>

注: ページ上でのアイコンの表示サイズはCSSで指定するので、viewBoxではsymbol内のどの部分を表示するかを指定します。

<use>で外部SVGファイルの<symbol>部分を参照する

SVGファイルをsvg/icons.svgとして保存した場合、HTMLでは以下のようにアイコンを呼び出します。symbolタグに#hogehogeのIDを持つ1つ目のアイコンを読み込むには、以下のように記述します。

<svg>
  <use xlink:href="svg/icons.svg#hogehoge" />
</svg>

これだけです。

ブラウザサポートを考えると面倒ですけど、基本的な仕組みはシンプルですね。

ブラウザサポート

XLinkとSVGのfragment identifierという仕組みを利用した方法なのですが、IEとEdgeを抜かしたSVGをサポートするモダンブラウザでサポートされているとのことです。とりあえず以下で動作確認できました:

  • Chrome 46 (Mac / Win)
  • Firefox 42 (Mac / Win)
  • Safari 9.0
  • Mobile Safari 9.0 (iOS 9.1)
  • Chrome Mobile 46 (Android 6)
  • Android 4.4 Chrome (BrowserStack / Nexus 5)
  • Android 4.1 Browser (BrowserStack / Galaxy S3)

IEでのサポート

IEはsvg4everybody というポリフィルを使ってフォールバックの実装が可能です。以下の仮想マシンでsvg4everybodyの動作確認ができました。

  • IE9 on Win 7
  • IE11 on Win 7
  • IE8 on Win 7(PNG画像にフォールバックされるところまでは動作確認できました)

MS Edgeでのサポート

Edge Dev のMSEdge on Win10 (Edge 20.10240.6384.0)で確認したところ、表示されませんでした。Edgeではuseを使った外部ファイルの読み込みがサポートされていないようなのですが、11月にリリースされたBuild 10586のEdgeHTML 13で機能が実装された とのことです。

用意するもの

さて、ここからはSVGスプライトを作る方法をまとめていきます。用意するのは以下の2つです。

  • SVGアイコン
  • Gulp環境

今回の検証のために作ったデモ・ファイルは全てgithub にアップしてありますので、良かったらご参照ください。

SVGアイコン

複数のアイコンを個別にSVGフォーマットで保存します。 svg/icons/など、決まったフォルダに保存しておきます。

Gulp環境

Gulpの方が設定ファイルなどの記述がシンプルで楽なのでGulpでやってます。以下のプラグインを使います。

gulp-load-plugins

各プラグインの読み込みを簡素化するためのプラグイン。なくても良いですけど、あるとgulpfile.jsの記述が便利です。

gulp-svgstore

複数のSVGアイコンを1つのSVGファイルにまとめてくれるプラグイン。

gulp-svgmin

SVGOでSVGファイルの最適化をするプラグイン。今回のデモでも、これを使ったら3KBくらい節約できました。

gulp-svg2png

SVGをPNGに変換してくれるプラグイン。フォールバック用のPNG画像を作るために使います。

gulp-imagemin

画像最適化プラグイン。自動変換したPNG画像の最適化に使います。

gulp-cheerio

HTMLとXMLの書き換えプラグイン。SVGに記述されているfillを削除したり、HTMLにインラインで<svg>を記述した場合に非表示にするためのクラスを追加します。

※ SVGでfillが指定されていると、CSSで色指定が出来なくなるので削除しておきます。fillが指定されていないとアイコンはデフォルトでは黒で表示されます。

gulp-rename

ファイル名を変更するプラグイン。フォールバック用のPNG画像ファイルの名称変更に使います。

導入ステップ

導入ステップをまとめると以下のようになります。

  1. SVGアイコンを特定のフォルダに保存
  2. gulpとプラグインのインストール
  3. gulpfile.jsの設定
  4. svg4everybodyの設置
  5. HTMLとCSSの記述

1. SVGアイコンを特定のフォルダに保存

SVGアイコンをsvg/icons/に保存します。gulp-svgstoreを使って、このフォルダに入れた複数のアイコンをsvg/icons.svgにまとめます。

2. gulpとプラグインのインストール

gulpと一覧にしたプラグインを全てインストールします。github package.jsonファイルをアップしてあるので良かったらご利用ください。

3. gulpfile.jsの設定

svgstoreを使って複数のSVGアイコンを1つのファイルに統合する設定を行う「svg」というタスクとフォールバック用のPNG画像を作成する「svg2png」というタスクの2つに分けてgulpfile.jsを設定します。

最終的なgulpfile.jsgithub にアップしてありますので、そちらをご参照ください。

まずはじめに、gulpとgulp-load-pluginsを読み込みます。gulp-load-pluginsでpackage.jsonにあるプラグインをここで読み込まなくても$.svgstoreなどと書いてで呼び出せるようにしています。

var gulp = require('gulp');
var $ = require('gulp-load-plugins')();

svgタスク

svg/icons/にあるSVGファイルを、まずはgulp-svgminで最適化して、gulp-svgstoreで1つのファイルに統合。統合したファイルをgulp-cheerioを使って編集しています。

gulp.task('svg', function () {
  gulp.src('svg/icons/*.svg')
    .pipe($.svgmin())
    .pipe($.svgstore({ inlineSvg: true }))
    .pipe($.cheerio({
      run: function ($, file) {
          $('svg').addClass('hide');
          $('[fill]').removeAttr('fill');
      },
      parserOptions: { xmlMode: true }
    }))
    .pipe(gulp.dest('svg'));
});

gulp-cheerioの説明の所でも書きましたが、SVGでfillが指定されていると、CSSで色指定が出来なくなるので削除します。fillが指定されていないとアイコンはデフォルトでは黒で表示されます。また、HTMLにインラインでSVGを読み込んで使用する場合にSVGスプライトが表示されないように<svg>hideというclassを追加しています。

svg2pngタスク

svg/icons/にあるSVGファイルをPNGに変換。svg4everbodyのデフォルトの動作に合わせてgulp-renameを使ってファイル名を変更します。その後、作成したPNGファイルをgulp-imageminを使って最適化します。PNG画像はicons.svgと同じsvgフォルダに保存します。

gulp.task('svg2png', function () {
  gulp.src('svg/icons/*.svg')
    .pipe($.svg2png(3))
    .pipe($.rename({ prefix: "icons.svg." }))
    .pipe($.imagemin())
    .pipe(gulp.dest('svg'));
});

4. svg4everbodyの設置

主にIE向けのポリフィルとしてsvg4everybody を設置します。githubからsvg4everybodyをダウンロードしてjsフォルダに保存します。デモページ ではIE8でテストするためにlegacy版を使いました。

IE9以上のサポート

IE9以上のサポートのみで良い場合は、<head>に置かなくても良いようです。

<script src="js/svg4everybody.min.js"></script>
<script>svg4everybody();</script>

IE6-8もサポートする場合

IE6-8もサポートする場合、<head>内でsvg4everybodyを読み込みます。

<script src="js/svg4everybody.legacy.min.js"></script>
<script>svg4everybody();</script>

また、以下を<head>内に記述します。

<meta http-equiv="X-UA-Compatible" content="IE=Edge">

5. HTMLとCSSの記述

あとはHTMLで以下のように記述すればアイコンを読み込めます。

HTML

#arrow-leftの部分は、ファイル名を指定します。

<svg role="image" class="icon">
    <use xlink:href="svg/icons.svg#arrow-left" />
</svg>

CSS

CSSでアイコンの表示サイズや色を指定します。.icon imgでは、フォールバックでPNG画像が読み込まれた際のスタイルを指定しています。

.icon {
    width: 32px;
    height: 32px;
    padding: 3px;
    border-radius: 4px;
    background: #ccc;
    fill: #fff;
}
.icon img {
    width: 32px;
    height: 32px;
    padding: 0;
    margin: 0;
}

最後に

お疲れさまでした!以上です!

これでアイコン管理が楽になりますね。

と、CSS-Tricksで紹介されている ようにIcomoon のようなサービスを使ってアイコンを管理するのもありだなぁと思って見ていたら、なんとGulpなしでもSVGスプライトを作ってくれるではないですか!しかも、外部SVGファイルの読み込みをサポートするためのIE9-11向けのポリフィル まで用意されてます。。。

あれ??こっちの方が簡単!?笑

次回は、Icomoonを使ったSVGスプライトの作り方をまとめてみたいと思います。。。

他のSVG関連の記事

こちらもご参考までにどうぞ:

参照

主に以下の2つのページでSVGスプライトの手法を学びました。つくづく、この人たちすごいなぁと感嘆するばかりです。いつもありがとうございます!

About the author

Rriverのステッカーが貼られたMacBookの向こうにいる自分のMemojiの似顔絵

「明日のウェブ制作に役立つアイディア」をテーマにこのブログを書いています。アメリカの大学を卒業後、ボストン近郊のウェブ制作会社に勤務。帰国後、東京のウェブ制作会社に勤務した後、ウェブ担当者として日英バイリンガルのサイト運営に携わる。詳しくはこちら

ウェブ制作・ディレクション、ビデオを含むコンテンツ制作のお手伝い、執筆・翻訳のご依頼など、お気軽にご相談ください。いずれも日本語と英語で対応可能です。まずは、Mastodon @rriver@vivaldi.net Twitter @rriver 、またはFacebook までご連絡ください。

“Gulpを使ったSVGスプライトのアイコンシステムとワークフローの作り方” への3件のフィードバック

  1. […] Gulpを使ったSVGスプライトのアイコンシステムとワークフローの作り方 – Rriver […]

  2. […] Gulpを使ったSVGスプライトのアイコンシステムとワークフローの作り方 – Rriver […]

  3. […] 以下のサイトを参考にさせていただきました。 Gulpを使ったSVGスプライトのアイコンシステムとワークフローの作り方 GulpでSVGスプライトとアイコン一覧を一発生成 […]